2016-06-16 3 views
4

Я столкнулся с class = std::enbale_if<condition, type>::type пару раз в списке параметров шаблона, знаю, что std::enable_if<B,T>::type делает, но не уверен, что делает class =? Я имею в виду, я знаю class type_name = type, но почему нет имени типа в class =? когда я его буду использовать?Тип шаблона вычет

Edit: Этот пример из here

template <class T, class U, class = typename enable_if 
      <is_lvalue_reference<T>::value ? is_lvalue_reference<U>::value : true>::type> 
inline T&& forward(U&& u) 
{ 
    return static_cast<T&&>(u); 
} 
+0

Это ошибка компиляции, вот что это такое. Ошибка компиляции, это просто параметр без имени шаблона. – SergeyA

+1

Отправьте образец, пожалуйста, чтобы мы могли обратиться к нему более непосредственно – vu1p3n0x

+0

Я отредактировал вопрос –

ответ

3

Это SFINAE (сбой замены не является ошибкой). Ниже приведены два примера, где ограничения помещаются в struct и class для отказа от экземпляров с типами, которые не были бы правильными.

но не уверен, что класс = делает? Я имею в виду, что я знаю class type_name = type, но почему нет имени типа в классе =? когда я его буду использовать?

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

http://coliru.stacked-crooked.com/a/25162a3eb107943f

// Allow only T to be floating type (!! actually static_assert would be preferred here) 
template<class T, 
     class = typename std::enable_if<std::is_floating_point<T>::value>::type> 
struct foo { 

}; 

template <class T, 
      class = typename std::enable_if<std::is_integral<T>::value>::type> 
bool is_even(T i) {return !bool(i%2);} 

int main() 
{ 
    // foo<int> f; //error 
    foo<float> f; //ok 

    //is_even(1.1); //error 
    is_even(1); //ok 

    return 0; 
} 

[править]

я должен сказать выше примеры не являются лучшими, и с помощью static_assert будет порекомендован, поскольку он позволяет генерировать информативные сообщения об ошибках. SFINAE не следует использовать для проверки параметров, а для выбора другой реализации в зависимости от предоставленных типов.

2

Это безымянный параметр типа шаблона. Так же, как вы можете оставить имя переменной в неиспользуемых параметрах функции, вы можете оставить имя параметра в параметрах шаблона без ссылок.

В конкретном случае std::enable_if<...>::type это используется исключительно для целей SFINAE. В частности, если логическое значение в enable_if ложно, вычет параметра шаблона не будет выполнен.