【问题标题】:c++11 enable_if error - template parameter re-declarationc++11 enable_if报错-模板参数重新声明
【发布时间】:2016-06-30 03:36:28
【问题描述】:

我正在尝试编译以下代码:

template <class T, typename std::enable_if<!std::is_fundamental<T>::value, int >::type = 0 >
class Calc
{
  public:
    int operator()( const T& v ) const {
        return v.getValue();
    }
};

template <class T, typename std::enable_if<std::is_fundamental<T>::value, int >::type = 0 >
class Calc : CalcBase <T>
{
};

编译时出现以下错误:

c.cpp:26: error: template parameter 'typename std::enable_if<(! std::is_fundamental::value), int>::type <anonymous>'
c.cpp:36: error: redeclared here as 'typename std::enable_if<std::is_fundamental::value, int>::type <anonymous>'

如果传递的模板参数是一个类,这里​​的目的是选择覆盖基类函数调用运算符的 Calc 版本。如果传递的参数是基本类型,那么我们选择不覆盖基类功能的 Calc 版本。 你能帮我理解我如何才能让它工作吗?

【问题讨论】:

  • 您需要展示更多代码。目前尚不清楚什么应该是主要模板,什么是/是专业化
  • 还不清楚这应该是什么意思:typename std::enable_if&lt;std::is_fundamental&lt;T&gt;::value, int &gt;::type = 0 类型何时以及为什么会等于零?通常我会认为答案是,永远不会。
  • @ChrisBeck 在他的例子中,typeint 的别名,int 可以是一个非类型模板参数,它可以有一个默认值(例如 0)。这实际上是从参与重载解析中删除函数的一种方法,因为当std::enable_if&lt;&gt; 的条件为假时,没有type 别名并且SFINAE 发生。
  • 我明白了,我以前从未见过那个。比较常见的是typename ENABLE = typename std::enable_if&lt;...&gt;::type
  • @ChrisBeck 和@user2296177。感谢您花时间查看我的问题。 Dietmar Kühl 提供了一个解决方案,解决了我的问题。感谢您的帮助。

标签: c++ templates c++11 stl enable-if


【解决方案1】:

我认为类模板声明不适用于 SFINAE:类模板不像函数模板那样重载。您正在声明两个具有相同名称的主类模板,这是不允许的。

方便的是,您的用例不需要 SFINAE:类模板支持部分特化。您只需使用默认的bool 参数并专门针对特征是truefalse 的类模板。例如:

template <class T, bool = std::is_fundamental<T>::value>
class Calc
{
  public:
    int operator()( const T& v ) const {
        return v.getValue();
    }
};

template <class T>
class Calc<T, false> : CalcBase <T>
{
};

【讨论】:

  • 这对我来说非常有效。确实是一个非常优雅的解决方案。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2018-09-17
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
相关资源
最近更新 更多