|
From: Mathieu Lacage on 28 Jan 2008 21:51 hi, The code below fails to compile with my g++ 4.1.1: class Base { public: virtual ~Base () = 0; }; Base::~Base () {} class Derived : public Base { public: virtual ~Derived () {} }; void Do (const Base &base) {} class A { public: operator Derived () const {return Derived ();} }; int main (int argc, char *argv[]) { Derived derived = A (); const Base &base = A (); Do (A ()); return 0; } with the following error: test.cc: In function 'int main(int, char**)': test.cc:27: error: cannot allocate an object of abstract type 'Base' test.cc:2: note: because the following virtual functions are pure within 'Base': test.cc:6: note: virtual Base::~Base() Which points to the line which calls function Do (A ()). I have to confess that I am a bit fumbled by this: I would have expected the line above const Base &base = A (); to also fail or to have both lines not fail. Anyhow, the question then is to know whether there is a way to make this code to compile and run to allow the compiler a way to guess the right type conversion when calling Do (const Base &). I could, of course, make A derive from Base but this (A) class (in my code) is really not expected to be polymorphic so, it kind of defeats the whole purpose of the exercise. Any hints ? regards, Mathieu -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Jiri Palecek on 29 Jan 2008 08:19 Mathieu Lacage wrote: > hi, Hi > The code below fails to compile with my g++ 4.1.1: .... > > Which points to the line which calls function Do (A ()). I have to confess > that I am a bit fumbled by this: I would have expected the line above > const Base &base = A (); to also fail or to have both lines not fail. > > Anyhow, the question then is to know whether there is a way to make this > code to compile and run to allow the compiler a way to guess the right > type conversion when calling Do (const Base &). I could, of course, make A > derive from Base but this (A) class (in my code) is really not expected to > be polymorphic so, it kind of defeats the whole purpose of the exercise. > > Any hints ? This is really interresting, because it compiles with Intel C++ compiler. However, the way I read 8.5.3, it should be impossible to initialize const Base& with A(), because the standard says ... a temporary of type cv1 T1 is created ... and T1 would be Base in this case, and there cannot be any temporary of type const Base. If you really want to use the conversion operator, you can invoke it explicitly Do((Derived)A()); however, I would prefer an explicit conversion function (like A().toDerived()) The question is, why does the standard allow implicit conversions like A -> const Derived& -> const Base& provided there's a conversion operator to const Derived& in A, and not A -> Derived -> const Base& when there's a conversion operator to Derived in A. Is that a defect or is there a reason for it? Regards Jiri Palecek -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alberto Ganesh Barbati on 29 Jan 2008 08:20 Mathieu Lacage ha scritto: > hi, > > The code below fails to compile with my g++ 4.1.1: > > class Base > { > public: > virtual ~Base () = 0; > }; > Base::~Base () {} > class Derived : public Base > { > public: > virtual ~Derived () {} > }; > > void Do (const Base &base) > {} > > class A > { > public: > operator Derived () const {return Derived ();} > }; > > > int main (int argc, char *argv[]) > { > Derived derived = A (); > const Base &base = A (); > Do (A ()); > > return 0; > } > > with the following error: > test.cc: In function 'int main(int, char**)': > test.cc:27: error: cannot allocate an object of abstract type 'Base' > test.cc:2: note: because the following virtual functions are pure within > 'Base': > test.cc:6: note: virtual Base::~Base() > > Which points to the line which calls function Do (A ()). I have to confess > that I am a bit fumbled by this: I would have expected the line above > const Base &base = A (); to also fail or to have both lines not fail. Looks like a bug in g++ to me. According to my interpretation of 8.5.3/5 both lines are ill-formed, because this rule applies: "a temporary of type �cv1 T1� is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5)" (where T1 is Base). Of course you cannot create a temporary of type Base because it's an abstract class. The funny thing is that g++ 3.4.5 agrees with my interpretation and chokes on both lines. > > Anyhow, the question then is to know whether there is a way to make this > code to compile and run to allow the compiler a way to guess the right > type conversion when calling Do (const Base &). I could, of course, make A > derive from Base but this (A) class (in my code) is really not expected to > be polymorphic so, it kind of defeats the whole purpose of the exercise. > > Any hints ? > The main problem here is that the A is only convertible to an rvalue of type Derived. If it could be made convertible to an *lvalue* of type Derived, then a different rule would apply, i.e.: the reference would bound directly to the lvalue result of the conversion. For example with this definition of A: class A { public: operator const Derived& () const { static Derived d; return d; } }; both lines compile correctly. HTH, Ganesh -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Fortran I/O design problem Next: stream bits: two different implementations, which is correct? |