【问题标题】:enable_if function defined when it shouldn't beenable_if 函数在不应该被定义的时候定义
【发布时间】:2012-01-04 23:53:34
【问题描述】:

作为一个实验,我正在尝试根据类模板参数创建一个没有参数的 void 成员函数更改行为:

#include <iostream>
#include <limits>

template<typename T>
class MyClass
{
public:
  void MyFunc(const typename std::enable_if<std::is_fundamental<T>::value, T> dummy = T());
  void MyFunc(const typename std::enable_if<!std::is_fundamental<T>::value, T> dummy = T());

};

template<typename T>
void MyClass<T>::MyFunc(const typename std::enable_if<std::is_fundamental<T>::value, T> dummy)
{
}

template<typename T>
void MyClass<T>::MyFunc(const typename std::enable_if<!std::is_fundamental<T>::value, T> dummy)
{
}

class Simple {};

int main(int argc, char *argv[])
{
  MyClass<int> myClass;
  myClass.MyFunc();

//   MyClass<Simple> myClass2;
//   myClass2.MyFunc();

  return 0;
}

但是,我得到:错误:重载“MyFunc()”的调用不明确。不应该只定义这些函数中的一个或另一个,因为除了 !在其中之一?

【问题讨论】:

  • downvoting ...您应该避免更改您的问题以包含我们告诉您的修复程序。它会让每个人感到困惑。请撤消该操作。

标签: c++ c++11 sfinae enable-if


【解决方案1】:

不,首先您需要实际访问enable_if::type typedef,其次,您的代码将不起作用,因为您的成员不是模板。其中一个总是最终成为无效声明。

应用必要的::type 修复后,在您尝试调用该成员之前很久,您的代码将在实例化MyClass&lt;int&gt; 时失败。

使您的成员成为成员模板,并使enable_if 依赖于成员模板的参数,而不是依赖于封闭类模板的参数。

【讨论】:

  • 好的,有没有办法做到这一点?有一个非模板化的成员函数会根据类的模板参数改变行为吗?
  • @DavidDoria 调用重载。 return MyFuncImpl(std::is_fundamental&lt;T&gt;());。重载 std::true_typestd::false_type 参数。
【解决方案2】:

您必须制作虚拟模板参数才能满足我的要求:

#include <iostream>
#include <limits>

template<typename T>
class MyClass
{
public:
  template <typename U = T>
  void MyFunc(const typename std::enable_if<std::is_fundamental<U>::value, U>::type dummy = U());
  template <typename U = T>
  void MyFunc(const typename std::enable_if<!std::is_fundamental<U>::value, U>::type dummy = U());
};

template<typename T>
template<typename U>
void MyClass<T>::MyFunc(const typename std::enable_if<std::is_fundamental<U>::value, U>::type dummy)
{
}

template<typename T>
template<typename U>
void MyClass<T>::MyFunc(const typename std::enable_if<!std::is_fundamental<U>::value, U>::type dummy)
{
}

class Simple {};

int main(int argc, char *argv[])
{
  MyClass<int> myClass;
  myClass.MyFunc();

  MyClass<Simple> myClass2;
  myClass2.MyFunc();

  return 0;
}

【讨论】:

    【解决方案3】:

    说:

    std::enable_if<std::is_fundamental<T>::value, T>::type
    //                                              ^^^^^^
    

    【讨论】:

    • 我首先尝试过(现在已编辑到原始帖子中)但我得到错误:在'struct std::enable_if'中没有​​名为'type'的类型
    • @DavidDoria:正确。当 bool 为 false 时,有 no 类型。这是不是 SFINAE 中的错误。
    • 其实这是一个错误,因为非模板中没有模板替换。
    • @visitor:确实,OP 仍然必须将此构建块集成到适当的 SFINAE 结构中。我只是想指出替换失败的发生位置。
    猜你喜欢
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多