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; 
} 

当我编译这与2015年VS更新3,然后我会得到的3D调用错误(见注释)。为什么?我不明白为什么不使用3d专业化。

THX 弗雷德

+0

我没有为什么,这是行不通的解释,需要检查C++标准为,但也有其他的方式,如果写这个你想要 – Raxvan

+1

[部分排序与功能模板具有undeduced上下文]可能的副本(http://stackoverflow.com/questions/1180325/partial-ordering-with-function-template-having-undeduced-context) –

+0

2原因,它的非推断的上下文,即使它可以推导出来,类型总是无效的 – Danh

回答

1

的问题是,你在一个non-deduced context

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

功能可能是这个职位的错误的工具(不能是部分专业),一个可能的解决方法如果你坚持使用功能可能是标签调度和专业化的组合

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