Re: automatic conversion
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! ]