5

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?

Barry
  • 286,269
  • 29
  • 621
  • 977
Jakob Riedle
  • 1,969
  • 1
  • 18
  • 21

1 Answers1

5

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".

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • Even if malformed?! That does not really make sence, especially in this case, where the Base class is explicitely made "private". – Jakob Riedle May 02 '15 at 16:39
  • I see, but isn't this a bug in the Standard? There is NO implicit conversion, not even an explicit. Thanks anyway! – Jakob Riedle May 02 '15 at 16:45
  • @JakobRiedle Overload resolution is one of the most complicated parts of C++ (IMHO). I wouldn't even dare to think that I know all rules in all cases, that I know what would be "right" or even "better" or how it all developed over time. :) I guess we'll just have to accept it as it is. – Daniel Frey May 02 '15 at 16:48
  • 2
    It's not template vs. non-template; that tiebreaker cannot distinguish between the two `func`s anyway because neither is a template. Derived-to-base conversion is considered a standard conversion sequence, which trumps a user-defined conversion sequence. – T.C. May 02 '15 at 16:53