2015-12-19 3 views
0

Я смотрел на следующей функции шаблона и было интересно, что происходит за кулисами, когда мы относим enable_if типа к typename ключевому слову:Назначение типа в TYPENAME ключевое слово

template <typename T, typename = std::enable_if<std::is_pointer<T>::value>::type> 
        // ^^ What happens here? 
void foo() 
{ 
    std::cout << "T is a pointer!" << std::endl; 
} 

Другое то очевидное SFINAE, компилятор действительно что-то с этим делает? Возможно, он генерирует какой-то анонимный тип?

Благодаря

+0

Это [неопределенный шаблонный параметр] (http://stackoverflow.com/questions/6718094/anonymous-template-typename-class-declarations) с аргументом по умолчанию. – LogicStuff

ответ

3

Я предполагаю, что вы используете компилятор, который не жалуется на недостающее ключевое слово typename после =.

Это необязательный шаблонный параметр, который иначе игнорируется вместе с аргументом шаблона по умолчанию, который будет использоваться, если не задан другой аргумент шаблона.

Это означает, что foo<void *>() разрешает foo<void *, std::enable_if<std::is_pointer<void *>::value>::type>(), что составляет foo<void *, void>().

Это означает, что foo<int>() разрешило бы к foo<int, std::enable_if<std::is_pointer<int>::value>::type>(), за исключением того, что отвергается, потому что std::enable_if<std::is_pointer<int>::value> не имеет никакого type члена.

Это означает, что foo<int, int>() работает и печатает «T - это указатель!», Поскольку аргумент по умолчанию не используется, если аргумент шаблона явно указан.

Это последнее означает, что это, вероятно, не очень хорошая идея.

+0

Так или иначе, я могу выполнить одно и то же (исключить экземпляр шаблона для типов без указателей) без аргумента по умолчанию (так что ваш пример 'foo () будет также терпеть неудачу)? –

+1

@user Обычный способ заключается в том, что вместо возвращаемого типа вместо аргумента по умолчанию следует использовать 'enable_if':' template auto foo() -> std :: enable_if_t > {...} ' , Вызывающий не может указать другой тип возврата. (Возможно, вам нужно будет использовать 'enable_if <...> :: type' и' is_pointer <...> :: value' как в вашем вопросе, если библиотека вашей реализации не обновлена, чтобы разрешить новые более короткие формы.) – hvd

+0

Meh, 'foo () 'для меня твердо на территории Макиавелли. –

1

Нет, мы не назначая enable_if типа к typename ключевому слову, параметр шаблона просто пропущен здесь, потому что он не будет использоваться:

template <typename T, typename Anonymous_Template_Parameter = std::enable_if<std::is_pointer<T>::value>::type> 
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

И = марки std::enable_if<std::is_pointer<T>::value>::type> в качестве аргумента по умолчанию здесь.

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