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

时间:2018-12-03 09:30:54

标签: c++ c++11 templates sfinae

我正在尝试为模板类提出一个成员函数:

  • 在模板类型为指针的情况下执行某些操作
  • 对非指针不起作用

不确定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:成员函数已经定义或声明

2 个答案:

答案 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
}

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

答案 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
    }