Search code examples
c++c++11ambiguityoverload-resolutionmalformed

Why is a malformed function used instead of an implicit conversion?


This is my Snippet:

class Base{};

class Derived : private Base{};

template<class T>
class Wrapper
{
    public:
        template<typename T2>
        Wrapper( T2&& )
        { }
};

// Function declarations
void func( Base& param );
void func( Wrapper<Derived> );
void funcUnambiguous( Wrapper<Derived> );


// Here is the Call:
Derived d = Derived();  
func( d );               // <- Error

GCC 4.9 gives me: error: 'Base' is an inaccessible base of 'Derived'

Whereas I do

Derived d = Derived();

funcUnambiguous( d );

it just works fine.

It seems like, any function only requiring a cheap cast, even if malformed, hides implicit, but expensive-cast functions. Does anybody have clue?


Solution

  • Updated, thanks to @T.C.

    Wrapper's ctor is a template user-defined conversion, hence the non-template standard conversion sequence overload with Base& takes precedence. The access check is only performed after selecting the overload - which is too late in your case.

    The complete rules are complicated, more can be found here, look at the section "Best viable function".