This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: c++/3708: [2003-01-02] static_cast between classes finds ambiguousbase conversion


The following reply was made to PR c++/3708; it has been noted by GNATS.

From: P Hornby <p.hornby@ned.dem.csiro.au>
To: Giovanni Bajo <giovannibajo@libero.it>
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 <class T>
 >    operator T () { return T (); }
 > };
 > 
 > class D : public B
 > {
 > public:
 >    D () {}
 > 
 >    operator Foo () { return Foo (); };
 > };
 > 
 > int main()
 > {
 >    D d;
 >    static_cast <Foo> (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 <class T> 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
 
 
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]