我有一个函数set_data
,必须针对接收的不同类型以不同的方式实现。例如,这正尝试基于输入类型实现两个重载。如果它是基本的,nonvoid
和non nullptr_t
,则在第一个实现中处理它。如果它是std::string
或char
缓冲区,请以其他方式处理。
struct field
{
template<typename TDataType, typename=void>
void set_data(TDataType data, size_t index = 0);
};
template<typename TDataType, typename = typename
std::enable_if< std::is_fundamental<TDataType>::value &&
std::is_same<TDataType, nullptr_t>::value == false &&
std::is_same<TDataType, void>::value == false>::type>
void field::set_data(TDataType data, size_t index /* = 0 */)
{
}
template<typename TDataType, typename = typename
std::enable_if< std::is_same<std::string const &, TDataType> ||
std::is_same<char const *, TDataType>>::type>
void field::set_data(TDataType data, size_t index /* = 0 */)
{
}
然后我打电话说:
field f;
int x = 10;
f.set_data(x);
编译器向我抛出错误。
defs.h(111): error C2995: 'void messaging::field::set_data(TDataType,size_t)' : function template has already been defined
我该如何解决?
在Visual Studio 2013上
在这样的模板参数上使用SFINAE无法正常工作,以为我不确定100%为何会这样(编辑: Agnew的回答说明这是因为模板无法区分)。如果改用std::enable_if
返回类型,并在类中移动定义,则它可以工作(已通过gcc和clang测试):
struct field
{
template<typename TDataType>
void set_data(TDataType data, size_t index = 0) {}
template<typename TDataType>
typename std::enable_if<std::is_fundamental<TDataType>::value &&
!std::is_same<TDataType, std::nullptr_t>::value &&
!std::is_same<TDataType, void>::value,
void>::type
set_data(TDataType data, size_t index /* = 0 */)
{
}
template<typename TDataType>
typename std::enable_if<std::is_same<std::string const &, TDataType>::value ||
std::is_same<char const *, TDataType>::value,
void>::type
set_data(TDataType data, size_t index /* = 0 */)
{
}
};
(我还修复了一些其他错误,即不要求int第二次重载的value
成员std::is_same
,并且不指定的名称空间std::nullptr_t
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句