2015-05-02 5 views
5

Это мой Отрывок:Почему используется некорректная функция вместо неявного преобразования?

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 дает мне: error: 'Base' is an inaccessible base of 'Derived'

В то время как я

Derived d = Derived(); 

funcUnambiguous(d); 

это просто отлично работает.

Кажется, что любая функция, требующая дешевого литья, даже если она искажена, скрывает неявные, но дорогостоящие функции. Кто-нибудь знает?

ответ

5

Обновлено, благодаря @ T.C. т е р

Wrapper «S является шаблономопределенного пользователя преобразованием, следовательно, не шаблонастандартного преобразования последовательности перегрузки с Base& имеет преимущество. Проверка доступа выполняется только после выбора перегрузки - что слишком поздно в вашем случае.

Полные правила сложны, больше можно найти here, посмотрите раздел «Наилучшая жизнеспособная функция».

+0

Даже если уродливые ?! Это не делает особого смысла, особенно в этом случае, когда базовый класс явно делается «частным». –

+0

Я вижу, но разве это не ошибка в стандарте? Нет никакого неявного преобразования, даже явного. Спасибо, в любом случае! –

+0

@JakobRiedle Разрешение перегрузки является одной из самых сложных частей C++ (IMHO). Я даже не осмелился бы думать, что во всех случаях я знаю все правила, что я знаю, что будет «правильным» или даже «лучше» или как все это будет развиваться с течением времени. :) Думаю, нам просто нужно принять это как есть. –