SFINAE не обнаруживает T :: эталон - PullRequest
4 голосов
/ 30 апреля 2011

Класс std::vector<T> является моделью концепции контейнера STL, и поэтому любая надлежащая реализация вектора должна включать вложенный typedef value_type, а также reference.Это должно быть обнаружено с помощью SFINAE.Однако в моих собственных тестах я могу использовать SFINAE для определения вложенной value_type typedef, но по какой-то причине я не могу обнаружить reference.

template <class T> 
typename T::value_type* test(T)
{
    cout << "Has nested typedef!" << endl;
}

template <class T> 
void test(...)
{
    cout << "Doesn't have nested typedef!" << endl;
}

int main()
{
    test(std::vector<int>());
}

.: Has nested typedef!

Однако, если я заменю value_type на reference, например:

template <class T> 
typename T::reference* test(T)
{
    cout << "Has nested typedef!" << endl;
}

template <class T> 
void test(...)
{
    cout << "Doesn't have nested typedef!" << endl;
}

int main()
{
    test(std::vector<int>());
}

... программа вообще не сможет скомпилироваться, выдав ошибку: error: no matching function for call to test(std::vector<int, std::allocator<int> >)

Почему метод SFINAE работает с T::value_type, но не с T::reference?

Ответы [ 2 ]

5 голосов
/ 30 апреля 2011

Что такое указатель на ссылку?

A : невозможно. Указатели на ссылки не могут существовать, поэтому ни одна из ваших функций не может существовать. Это отличается от вашего первого случая, когда может существовать хотя бы одна из функций (и таким образом вы получаете компиляцию, компоновку и вывод).

Интересно, что SFINAE здесь работает , так как определение функции не вызывает ошибку компиляции. Он пытается вызвать функцию, которая из-за невозможности + SFINAE не существует, и это вызывает ошибку. :)

2 голосов
/ 30 апреля 2011

typename T :: reference * test (T)

Указатели на ссылки недопустимы в C ++.

§8.3.2 / 4 из Стандарта гласит:

Не должно быть ссылок на ссылки, массивов ссылок и указателей на ссылки .

...