【问题标题】:How to use enable_if in a class obj?如何在类 obj 中使用 enable_if?
【发布时间】:2013-11-07 05:38:16
【问题描述】:

下面的代码是可以的:

template <class T>
std::enable_if<std::is_atomic<T>::value, bool>
foo(T t) { return true; }

template <class T>
std::enable_if<tmp::is_sequence<T>::value, bool>
foo(T t) { return false; }

int main(void){
  foo(1);  // return true
  auto std::vector<int> a{2};
  foo(a);  // return false
}

但是当我使用一个类来捆绑它们时,却无法编译:

template <class T>
class test {
public:

std::enable_if<std::is_atomic<T>::value, bool>
foo(T t) { return true; }

std::enable_if<tmp::is_sequence<T>::value, bool>
foo(T t) { return false; }
};

int main(...) {
  test<int> obj;
  obj.foo(1);
  test<std::vector<int>> obj2;
  std::vector<int> tmp{2};
  obj2.foo(tmp);
}

clang++ 打印:

error: functions that differ only in their return type cannot be overloaded

所以我写了一些东西来欺骗编译器(在第二个foo添加一个S):

template <class S>
std::enable_if<tmp::is_sequence<T>::value, bool>
foo(T t) { return false; }

还是不行:

error: no type named 'type' in 'std::enable_if<false, bool>'

如何让它在课堂上发挥作用?

【问题讨论】:

  • 嗯。什么库公开std::Enable_if?还是你的意思是std::enable_if
  • @WhozCraig 对拼写错误感到抱歉
  • 您正在尝试将 SFINAE 应用于不是函数模板的内容。那是行不通的。 T 不是推论出来的 - 它在你专攻 test 的那一刻就已经确定了。对于给定的test&lt;X&gt;,该类有两个普通(非模板)成员函数,都带有签名bool foo(X)

标签: c++ class c++11 overloading enable-if


【解决方案1】:

您忘记在 enable_if 之后添加 ::type:(参见 enable_if

template <class T> std::enable_if<std::is_atomic<T>::value, bool>::type
foo(T t) { return true; }

【讨论】:

    【解决方案2】:

    两个成员函数应该有不同的模板参数(以下可以正常工作)

    template <class T>
    class test {
    public:
    
    template<typename U>
    typename std::enable_if<std::is_atomic<U>::value, bool>::type
    foo(U t) { return true; }
    
    template<typename U>
    typename std::enable_if<tmp::is_sequence<U>::value, bool>::type
    foo(U t) { return false; }
    
    };
    

    【讨论】:

    • 是的,我重新定义了它,你可以认为我的代码中的 std::enable_if 是我的版本。这不是这个问题的重点。
    • 此时,T 毫无用处,test 也可以是常规(非模板)类,甚至是命名空间。
    【解决方案3】:

    如果你真的想做你正在做的事,经典的成语是引入一个带有默认值的假 SFINAE 参数:

    bool foo(T t, std::enable_if<..., void*> = nullptr) { ... }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-20
      • 1970-01-01
      • 2016-04-27
      • 2014-02-18
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多