基于模板类型指针的条件函数行为

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
}

LIVE

或者在非类型模板参数列表中使用它们,例如(对于 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";
}

LIVE

问题在于这两个函数模板声明等价,因此编译器认为您的代码包含一个唯一函数的 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
    }