base/derived ambiguity with gcc, but not with MSVC

  • Thread starter =?ISO-8859-1?Q?Christian_Engstr=F6m?=
  • Start date
?

=?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;
}
 
A

Alf P. Steinbach

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?

I get the above errors with g++ 3.2.3, but it compiles fine with g++ 3.3.

A compiler upgrade seems to be in order... ;-)
 
?

=?ISO-8859-1?Q?Christian_Engstr=F6m?=

Alf said:
I get the above errors with g++ 3.2.3, but it compiles fine with g++ 3.3.

A compiler upgrade seems to be in order... ;-)

Yes, that was it, it seems. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top