3

У меня есть простой основной шаблон функции, который я хочу частично специализировать.C++ шаблон специализации с std :: enable_if не работает

template< typename T > 
void SetAttribute(const T& value) 
{ 
    static_assert(false, "SetAttribute: wrong type!"); 
} 

template<> void SetAttribute(const bool& value) {} 

template<> void SetAttribute(const std::wstring& value) {} 

template< typename T > 
void SetAttribute(const typename std::enable_if< std::is_integral<T>::value >::type& value) {} 

int main() 
{ 
    SetAttribute(std::wstring(L"bla")); 
    SetAttribute(bool(true)); 
    SetAttribute(std::uint32_t(1)); // error C2338: SetAttribute: wrong type! 

    return 0; 
} 

Когда я компилирую это с VS 2015 Update 3, затем я получаю сообщение об ошибке на 3 вызова (см комментарий). Зачем? Я не понимаю, почему 3D-специализация не используется.

Thx Фред

+0

я не объяснение того, почему это не работает, необходимо проверить C++ стандарт для этого, но есть и другие способы, чтобы написать это, если вы хотите – Raxvan

+1

Возможный дубликат [Частичное упорядочение с шаблоном функции с неопределенным контекстом] (http://stackoverflow.com/questions/1180325/partial-ordering-with-function-template-having-undeduced-context) –

+0

2 причина, это невыводимый контекст, даже если он может быть выведен, тип всегда недействителен – Danh

ответ

1

Проблема заключается в том, что вы используете T в non-deduced context

template< typename T > 
void SetAttribute(const typename std::enable_if< std::is_integral<T>::value >::type& value) {} 
                    ^

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

template<class T> 
void SetAttribute(const T&, std::true_type) {} 

template<class T> 
void SetAttribute(const T& value, std::false_type) 
{ 
    static_assert(std::is_integral<T>::value, "SetAttribute: wrong type!"); 
} 

template< typename T > 
void SetAttribute(const T& value) 
{ 
    SetAttribute(value, std::is_integral<T>()); 
} 

template<> void SetAttribute(const bool&) {} 

template<> void SetAttribute(const std::wstring&) {} 

Example

Довольно нечитаемым, если вы спросите меня ..

+0

В качестве альтернативы вы можете использовать enable_if по типу возвращаемого значения или по аргументу по умолчанию параметра шаблона. – ymett

+0

@ymett: Я пробовал, но не работает ... или, возможно, я сделал это неправильно? – Fred

+0

@Fred Что именно вы делали и что именно произошло? – ymett

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