From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4912 invoked by alias); 1 May 2003 01:26:00 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 4898 invoked by uid 71); 1 May 2003 01:26:00 -0000 Date: Thu, 01 May 2003 01:26:00 -0000 Message-ID: <20030501012600.4897.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: P Hornby Subject: Re: c++/3708: [2003-01-02] static_cast between classes finds ambiguous base conversion Reply-To: P Hornby X-SW-Source: 2003-05/txt/msg00006.txt.bz2 List-Id: The following reply was made to PR c++/3708; it has been noted by GNATS. From: P Hornby To: Giovanni Bajo Cc: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org, gcc-prs@gcc.gnu.org, nathan@gcc.gnu.org Subject: Re: c++/3708: [2003-01-02] static_cast between classes finds ambiguous base conversion Date: Thu, 01 May 2003 09:16:19 +0800 Long ago I eliminated the template, to get class Foo { public: Foo() {} Foo(int) {} }; class B { public: B() {} operator int () { return 1; } }; class D : public B { public: D () {} operator Foo () { return Foo(1); }; }; int main() { D d; Foo foo = (Foo) d; return 0; } I seem to recall that D's methods are to be preferred over any of B's in the event of such conflicts. I also recall something that implied that such conflict resolution had a limit on the complexity, and that this limit was greater than a single direct call to a method of a class. I think it was in BS's C++ ANSI book, but it was so long ago that I forget. In any case, the template version of the conflict is excluded on the grounds that the D::operator Foo() -> Foo::Foo(const Foo&) requires no template instantiation. (under the rule that the less instantiated resolution yields to the more instantiated (in this case explict) resolution). This would be the case if the conflict were to arise from a D::operator T(), so why break the rule for B::operator T()? (I know why the compiler is doing this, and it is very hard to fix. I understand why you are keen to close it). As I've stated elsewhere g++ (and now Comeau) are the only compilers I have encountered that do not resolve this conflict. I only ask that you consider this once more before closing it. (You may run into a language lawyer next time). > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=3708 > > I think there is nothing wrong with this. Nathan's epurated code (for > reference) is: > ----------------------------------------- > class Foo > { > public: > Foo() {} > Foo(int) {} > }; > > class B > { > public: > B() {} > > template > operator T () { return T (); } > }; > > class D : public B > { > public: > D () {} > > operator Foo () { return Foo (); }; > }; > > int main() > { > D d; > static_cast (d); > return 0; > } > > ----------------------------------------- > pr3708.cpp: In function `int main()': > pr3708.cpp:39: error: call of overloaded `Foo(D&)' is ambiguous > pr3708.cpp:4: note: candidates are: Foo::Foo(const Foo&) > pr3708.cpp:7: note: Foo::Foo(int) > > It makes sense to me, because there are two ways the compiler can perform > the conversion: > > 1) using D::operator Foo(), and then calling the implicit copy constructor > Foo::Foo(const Foo&) > 2) using template B::operator T(), specialized as B::operator > int(), and then calling the constructor Foo::Foo(int) > > The two ways look both perfectly feasable to me, so I think this is not a > bug. As a further confirmation, Comeau rejects the code in the same way. > > If no language lawyer objects, I will close this PR. > > Giovanni Bajo