使用std :: enable_if的c ++模板特化

时间:2016-12-07 08:41:45

标签: c++ templates template-specialization partial-specialization

我有一个简单的主要功能模板,我想部分专门化。

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编译它时,我将在3d调用上收到错误(请参阅注释)。为什么?我不明白为什么不使用3d专业化。

THX 佛瑞德

1 个答案:

答案 0 :(得分:1)

问题是您在non-deduced context

中使用T
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

如果你问我,真是难以辨认......