ambiguous

T

Tim H

Why is this ambiguous:

------------------------------------------------
#include <boost/shared_ptr.hpp>

class base {};
class derived: public base {};
class other {};

void do_something(const boost::shared_ptr<other> dev) {}
void do_something(const boost::shared_ptr<base> scope) {}

int main()
{
boost::shared_ptr<base> b(new base());
boost::shared_ptr<derived> d(new derived());

do_something(b);
do_something(d);

return 0;
}
------------------------------------------------

but this is not

------------------------------------------------
class base {};
class derived: public base {};
class other {};

void do_something(const other *dev) {}
void do_something(const base *scope) {}

int main()
{
base *b = new base();
derived *d = new derived();

do_something(b);
do_something(d);

return 0;
}
-------------------------------------------------------

and this is also allowed

------------------------------------------------------
#include <boost/shared_ptr.hpp>

class base {};
class derived: public base {};
class other {};

void do_something(const boost::shared_ptr<base> scope) {}

int main()
{
boost::shared_ptr<base> b(new base());
boost::shared_ptr<derived> d(new derived());

do_something(b);
do_something(d);

return 0;
}
 
A

Alan Johnson

Tim said:
Why is this ambiguous:

------------------------------------------------
#include <boost/shared_ptr.hpp>

class base {};
class derived: public base {};
class other {};

void do_something(const boost::shared_ptr<other> dev) {}
void do_something(const boost::shared_ptr<base> scope) {}

int main()
{
boost::shared_ptr<base> b(new base());
boost::shared_ptr<derived> d(new derived());

do_something(b);
do_something(d);

return 0;
}
------------------------------------------------

but this is not

------------------------------------------------
class base {};
class derived: public base {};
class other {};

void do_something(const other *dev) {}
void do_something(const base *scope) {}

int main()
{
base *b = new base();
derived *d = new derived();

do_something(b);
do_something(d);

return 0;
}

In your second example, the type 'derived *' has relationship to the
type 'base *' that is well defined by the standard. Specifically,
pointers to derived are convertible to pointers to base.

In your first example, the type 'shared_ptr<derived>' has no particular
relation to the type 'shared_ptr<base>'. That is, shared_ptr<derived>
is not convertible to shared_ptr<base> any more than
std::vector<derived> would be convertible to std::vector<base>.

shared_ptr does have a template constructor, though, that can accept
type shared_ptr<T>. The problem from the compiler's perspective is
whether it should instantiate that template with T = base or T = other,
thus, ambiguity.
 
J

James Kanze

[...]
shared_ptr does have a template constructor, though, that can accept
type shared_ptr<T>. The problem from the compiler's perspective is
whether it should instantiate that template with T = base or T = other,
thus, ambiguity.

Just a small addition to a very good explination: the important
point to keep in mind is that the compiler does overload
resolution before it instantiates the chosen template function.
So it cannot know that the conversion will cause an error if it
is instantiated with other.

There is a proposal (more than one, in fact) to add concepts to
the language. As I understand it, this will allow expression of
requirements like the fact that the template conversion
constructor requires the pointers to the underlying types to be
implicitly convertable. I'm not really sure of the details, but
presumably, such constraints will play a role in template type
deduction, ensuring that the conversion to other will not be
instantiated here, and thus that overload resolution will work.
So maybe sometime in the future...
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top