?
=?ISO-8859-1?Q?Christian_Engstr=F6m?=
When I compile the below program with Microsoft Visual C++ version 6, I
get the results I expect, which is that the program should write out
base()
derived()
base()
derived(derived)
When I try to compile it with gcc, I instead get the compiler error message
test_prog.cpp: In function `int main(int, char**)':
test_prog.cpp:43: call of overloaded `derived(derived_handle&)' is ambiguous
test_prog.cpp:18: candidates are: derived::derived(const base&)
test_prog.cpp:17: derived::derived(const derived&)
Why is this?
The statement that causes the problem is
derived d(my_dhandle); // <-- Ambiguous according to gcc
but I really can't understand why it should be considered ambiguous.
The class 'derived' has both a copy constructor and a constructor that
takes a 'base' object as input, and the handle 'my_dhandle' has an
automatic conversion to 'derived&', so I would have expected the
compiler to prefer the constructor that is the closest match for the
actual parameter, and pick the constructor 'derived(const derived&)'
over 'derived(const base&)'.
But it doesn't, so evidently I've missed something. But what?
(ps. I'm aware that the test program as it is written here would leak
memory, but that's not the problem right now, since I can't even get it
to compile.)
==============================================================================
test_prog.cpp:
#include <iostream>
//----------------------------------------------------------------------------
class base
{
public:
base() {std::cout << "base()" << std::endl;}
base(const base&) {std::cout << "base(base)" << std::endl;}
};
//----------------------------------------------------------------------------
class derived : public base
{
public:
derived() {std::cout << "derived()" << std::endl;}
derived(const derived&) {std::cout << "derived(derived)" <<
std::endl;}
explicit derived(const base&) {std::cout << "derived(base)" <<
std::endl;}
};
//----------------------------------------------------------------------------
class derived_handle
{
derived* tptr;
public:
derived_handle() {};
derived_handle(derived* inptr) : tptr(inptr) {}
derived& operator*() const {return *tptr;}
derived* operator->() const {return tptr;}
operator derived&() const {return **this;} // Implicit conversion
to 'derived'
};
//============================================================================
int main (int argc, char* argv[])
{
derived_handle my_dhandle(new derived());
derived d(my_dhandle); // <-- Ambiguous according to gcc
return 0;
}
get the results I expect, which is that the program should write out
base()
derived()
base()
derived(derived)
When I try to compile it with gcc, I instead get the compiler error message
test_prog.cpp: In function `int main(int, char**)':
test_prog.cpp:43: call of overloaded `derived(derived_handle&)' is ambiguous
test_prog.cpp:18: candidates are: derived::derived(const base&)
test_prog.cpp:17: derived::derived(const derived&)
Why is this?
The statement that causes the problem is
derived d(my_dhandle); // <-- Ambiguous according to gcc
but I really can't understand why it should be considered ambiguous.
The class 'derived' has both a copy constructor and a constructor that
takes a 'base' object as input, and the handle 'my_dhandle' has an
automatic conversion to 'derived&', so I would have expected the
compiler to prefer the constructor that is the closest match for the
actual parameter, and pick the constructor 'derived(const derived&)'
over 'derived(const base&)'.
But it doesn't, so evidently I've missed something. But what?
(ps. I'm aware that the test program as it is written here would leak
memory, but that's not the problem right now, since I can't even get it
to compile.)
==============================================================================
test_prog.cpp:
#include <iostream>
//----------------------------------------------------------------------------
class base
{
public:
base() {std::cout << "base()" << std::endl;}
base(const base&) {std::cout << "base(base)" << std::endl;}
};
//----------------------------------------------------------------------------
class derived : public base
{
public:
derived() {std::cout << "derived()" << std::endl;}
derived(const derived&) {std::cout << "derived(derived)" <<
std::endl;}
explicit derived(const base&) {std::cout << "derived(base)" <<
std::endl;}
};
//----------------------------------------------------------------------------
class derived_handle
{
derived* tptr;
public:
derived_handle() {};
derived_handle(derived* inptr) : tptr(inptr) {}
derived& operator*() const {return *tptr;}
derived* operator->() const {return tptr;}
operator derived&() const {return **this;} // Implicit conversion
to 'derived'
};
//============================================================================
int main (int argc, char* argv[])
{
derived_handle my_dhandle(new derived());
derived d(my_dhandle); // <-- Ambiguous according to gcc
return 0;
}