2016-05-04 1 views
2

Пройдя некоторые из концепций C++, я наткнулся на логику std :: is_base_of.Логика std :: is_base_of в C++ 11

Взаимодействуя по логике, выдается код ниже, но я не могу его понять.

Может ли кто-нибудь объяснить мне, как это работает?

template<typename D, typename B> 
class IsDerivedFromHelper 
{ 
    class No { }; 
    class Yes { No no[3]; }; 

    static Yes Test(B*); 
    static No Test(...); 
public: 
    enum { Is = sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) }; 

}; 


template <class C, class P> 
bool IsDerivedFrom() { 
    return IsDerivedFromHelper<C, P>::Is; 
} 
+4

@KerrekSB Где находится SFINAE выше? – Yakk

+0

@Barry связанный вопрос объясняет другой код. Они оба являются попытками 'is_base_of', но связанный выглядит так, как будто он решает проблему частного наследования, тогда как (насколько я предполагаю) вышеупомянутый не делает (и проще в результате). Neeraj, вы хотите знать, как 'is_base_of' может быть реализован на языке, или вы хотите знать, как работает ваш код? – Yakk

+2

@KerrekSB: Не так ли? Похоже на базовое разрешение перегрузки для меня. 'D *' неявно преобразуется в 'B *' iif (ish) 'B' является базой' D'. Эта перегрузка возвращает значение типа «Да», которое в три раза больше размера «Нет», с которым вы можете проверить «sizeof». Все остальные случаи приводят к вызову перегрузки '...', которая возвращает 'No'. И глазурь на торте состоит в том, что все это в неоценимом контексте, поэтому на самом деле ничего не вызывается, и все это можно использовать как константу времени компиляции. –

ответ

1

Когда B является базовым классом D, вызов Test(static_cast<D*>(0)) решает Yes Test(B*). В противном случае он разрешает No Test(...).

Если B является базовым классом D, то значение sizeof(Test(static_cast<D*>(0))) равно sizeof(Yes). В противном случае он равен sizeof(No).

Yes и No определены так, чтобы sizeof(Yes) не был равен sizeof(No).

Если B является базовым классом D,

sizeof(Test(static_cast<D*>(0))) == sizeof(Yes) 

вычисляет true. В противном случае он оценивается до false.

+0

Спасибо R Sahu. Наверняка, мне не хватает некоторых основ. Какова роль 0 (выражение), которая передается в операторе static_cast? – Neeraj

+2

@Neeraj Это старая школа 'nullptr' – Yakk