2016-03-30 3 views
2

Я просматривал документацию SFINAE и там был этот шаблон декларации:Безымянный класс/имяТипа в качестве аргументов шаблона

template<typename SomeType> 
struct inner_type { typedef typename SomeType::type type; }; 
template < 
    class T, 
    class = typename T::type,   // SFINAE failure if T has no member type 
    class U = typename inner_type<T>::type // hard error if T has no member type 
              // (guaranteed to not occur as of C++14) 
> void foo(int) {} 

В частности, я спрашиваю о class = typename T::type. Какой смысл объявлять неназванный класс?

Из-за комментария, я думал, что это приведет к ошибке компиляции, когда T не член type, но это не так, поскольку foo<int, int, int>(0); отлично компилируется.

С другой стороны

template<class T, typename = std::enable_if_t<std::is_unsigned<T>::value>> 
void foo(T t) {} 

не компилируется, если T подписан, и компилирует, если T не подписан.

Что мне здесь не хватает?

+2

Похоже, вы должны только называть 'foo'' 'foo (0)' вместо того, чтобы переопределять параметры шаблона, которые удаляют шаблон из перегрузки. – phantom

ответ

3

foo<int, int, int>(0); компилируется в порядке.

Поскольку вы указать 2-й аргумент шаблона, то шаблон по умолчанию довод (т.е. typename T::type) не будет использоваться, то не вызовет ошибку компиляции.

Если вы просто пишете foo<int>(0);, чтобы использовать аргумент шаблона по умолчанию, компиляция завершится с ошибкой.

LIVE

И это же для 2-го образца тоже.

Какой смысл объявлять неназванный класс?

Поскольку параметр шаблона не будет использоваться для реализации шаблона.

Смежные вопросы