C++模板特化与std::enable_if无法工作

3
我有一个简单的主函数模板,我想要进行部分特化。
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更新3编译此代码时,第三个调用会出现错误(请参见注释)。为什么?我不明白为什么没有使用第三个特化版本。
谢谢, Fred

我不知道为什么这个不起作用,需要检查C++标准,但如果您愿意,还有其他的写法。 - Raxvan
1
可能是具有未推断上下文的函数模板的部分排序的重复问题。 - Edgar Rokjān
两个原因,它是非推断上下文,即使可以推断,类型始终为void。 - Danh
std::enable_if< std::is_integral< T >::value >::type 中,T 无法被推导。 - Jarod42
@Fred 使用两个结构体invalidintegrals,并使用静态函数进行实现,然后在SetAttribute中使用std::conditional来选择您想要的结构体。http://en.cppreference.com/w/cpp/types/conditional - Raxvan
显示剩余4条评论
1个回答

1
问题在于你正在非推断上下文中使用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&) {}

示例

如果你问我,这很难读懂。


或者你可以在返回类型上使用enable_if,或者在模板参数默认参数上使用。 - ymett
@ymett:我已经尝试过了,但还是不行...或许是我搞错了? - Fred
@Fred,你到底做了什么,发生了什么事情? - ymett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接