基于模板类型指针的条件函数行为
Conditional function behavior based on pointer-ness of template type
我正在尝试为模板 class 想出一个成员函数:
- 在模板类型是指针的情况下做一些事情
- 对非指针不做任何事情
不确定 SFINAE 是否适用于此,因为我需要两个版本,因为我在 class 本身中调用它们。请注意我仅限于 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
}
编译器报错error C2535: member function already defined or declared.
问题是默认模板参数不是 function template signature 的一部分。这两个 SomeFunction
被认为是相同的,然后导致重新声明错误。
Two function templates are considered equivalent if
- they are declared in the same scope
- they have the same name
- they have identical template parameter lists
- the expressions involving template parameters in their return types and parameter lists are equivalent
您可以在 return 类型中使用它们,例如(对于 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";
}
问题在于这两个函数模板声明等价,因此编译器认为您的代码包含一个唯一函数的 2 个函数定义。
[temp.over.link]/6 and [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
}
我正在尝试为模板 class 想出一个成员函数:
- 在模板类型是指针的情况下做一些事情
- 对非指针不做任何事情
不确定 SFINAE 是否适用于此,因为我需要两个版本,因为我在 class 本身中调用它们。请注意我仅限于 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
}
编译器报错error C2535: member function already defined or declared.
问题是默认模板参数不是 function template signature 的一部分。这两个 SomeFunction
被认为是相同的,然后导致重新声明错误。
Two function templates are considered equivalent if
- they are declared in the same scope
- they have the same name
- they have identical template parameter lists
- the expressions involving template parameters in their return types and parameter lists are equivalent
您可以在 return 类型中使用它们,例如(对于 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";
}
问题在于这两个函数模板声明等价,因此编译器认为您的代码包含一个唯一函数的 2 个函数定义。
[temp.over.link]/6 and [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
}