Почему это работает (шаблоны, SFINAE).C ++ - PullRequest
7 голосов
/ 17 марта 2010

со ссылкой на вчерашний пост, это разбудило меня этим утром. Почему это на самом деле работает? Что касается функции test, эта функция не имеет тела, так как она может выполнять что-либо? Я хочу знать, почему и как это работает? Мне ДЕЙСТВИТЕЛЬНО интересно видеть ваши ответы.

template<typename T> 
class IsClassT { 
  private: 
    typedef char One; 
    typedef struct { char a[2]; } Two; 
    template<typename C> static One test(int C::*); //NO BODY HERE
    template<typename C> static Two test(…); //NOR HERE
  public: 
    enum { Yes = sizeof(IsClassT<T>::template test<T>(0)) == sizeof(One) }; 
    enum { No = !Yes }; 
}; 

Заранее спасибо с помощью, чтобы понять это очень интересное явление.

Ответы [ 2 ]

8 голосов
/ 17 марта 2010
  1. Вы не можете получить ошибку компилятора, потому что test -функция объявление существует.

  2. Вы не можете получить ошибку компоновщика, поскольку вы не вызываете функцию test.

C ++ Стандарт ИСО / МЭК 14882: 2003 (E)

5.3.3 Размер

Оператор sizeof возвращает количество байтов в объект представления своего операнда. Операнд является либо выражением, который не оценивается , или заключенный в скобки идентификатор типа. Размер оператор не должен ...

...

6 голосов
/ 17 марта 2010

Полагаю, вы ссылаетесь на перечисление Yes? IsClassT<T>::test<T>(0)? sizeof на самом деле не оценивает свои аргументы. Вот почему код, подобный следующему, является законным, даже если вы ожидаете, что он вам поможет:

int* p = 0;
int sizeof_int = sizeof(*p); //oops, p is 0 :(
...