我正在尝试为模板类提出一个成员函数:
不确定SFINAE是否适用于此,因为在类本身中调用它们时,我需要两个版本。请注意,我仅限于C ++ 11。
template < typename T_ = T, typename = std::enable_if_t <!std::is_pointer<T_>{} > >
void SomeFunction()
{
// Do nothing
}
template < typename T_ = T, typename = std::enable_if_t < std::is_pointer<T_>{} > >
void SomeFunction()
{
// Do sth
}
编译器抱怨错误C2535:成员函数已经定义或声明。
答案 0 :(得分:3)
问题在于默认模板参数不是function template signature的一部分。这两个SomeFunction
被认为是相同的,然后导致重新声明错误。
如果两个功能模板被认为是等效的
- 它们在同一范围内声明
- 它们的名字相同
- 它们具有相同的模板参数列表
- 在返回类型和参数列表中涉及模板参数的表达式是等效的
您可以在返回类型中使用它们,例如(对于C ++ 11)
template <typename T_ = T>
typename std::enable_if<!std::is_pointer<T_>::value>::type SomeFunction()
{
// Do nothing
}
template <typename T_ = T>
typename std::enable_if<std::is_pointer<T_>::value>::type SomeFunction()
{
// Do sth
}
或在非类型模板参数列表中使用它们,例如(对于C ++ 11)
template < typename T_ = T, typename std::enable_if<!std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
{
// Do nothing
std::cout << "Do nothing\n";
}
template < typename T_ = T, typename std::enable_if<std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
{
// Do sth
std::cout << "Do sth\n";
}
答案 1 :(得分:2)
问题在于两个函数模板声明是 equivalent ,因此编译器认为您的代码包含2个函数定义,用于一个唯一函数。
功能模板的等效性在[temp.over.link]/6和[temp.over.link]/7中进行了描述。
在您的特定情况下,问题在于此等效性没有考虑默认模板参数。
如果添加默认的模板参数,则这两个函数将不等效:
template < typename T_ = T
, typename = std::enable_if_t <!std::is_pointer<T_>{} > >
void SomeFunction()
{
// Do nothing
}
template < typename T_ = T
, class=void
, typename = std::enable_if_t < std::is_pointer<T_>{} > >
void SomeFunction()
{
// Do sth
}