【问题标题】:How is enable_if used for removing codeenable_if 如何用于删除代码
【发布时间】:2016-12-07 14:27:50
【问题描述】:

我正在使用 enable_if 语句来删除考虑中的可能方法。

#include "gmpxx.h"
#include <iostream>

template <typename T>
struct is_ring_field {
};

template <>
struct is_ring_field<int> {
  static const bool value = false;
};

template <>
struct is_ring_field<mpq_class> {
  static const bool value = true;
};

template<typename T>
std::enable_if<is_ring_field<T>::value,int> RankMat(T const& Input)
{
  return 10;
}

template<typename T>
std::enable_if<(not is_ring_field<T>::value),int> RankMat(T const& Input)
{
  return 20;
}

int main()
{
  int M1=10;
  mpq_class M2=3;
  std::cerr << "FICT rank(M1)=" << RankMat(M1) << "\n";
  std::cerr << "FICT rank(M2)=" << RankMat(M2) << "\n";
}

最终目标是拥有根据输入的代数数据类型而变化的方法。对于其他特征,它对我有用,但不是这个。在这种情况下,编译器奇怪地说调用不明确,换句话说,std::enable_if 失败了。

【问题讨论】:

  • 查看RankMat 的两个重载。重载的哪一部分不同?该部分是否可以是函数中唯一不同于有效重载的部分?
  • 你没有忘记typename std::enable_if&lt;*,*&gt;::type吗?
  • 是的,我是在写完信息后才知道的,对此感到抱歉。来自 clang++ 和 g++ 的消息都没有帮助。

标签: c++ c++11 template-meta-programming enable-if


【解决方案1】:

std::enable_if&lt;&gt; 是有效类型;您需要将其type 成员用于 SFINAE:

template<typename T>
typename std::enable_if<is_ring_field<T>::value,int>::type RankMat(T const& Input)
{
  return 10;
}

template<typename T>
typename std::enable_if<(not is_ring_field<T>::value),int>::type RankMat(T const& Input)
{
  return 20;
}

【讨论】:

    【解决方案2】:

    你只是把它放在了错误的位置。 试试这个:

    template<typename T>
    int RankMat(T const& Input, typename std::enable_if<is_ring_field<T>::value,T>::type* = 0)
    {
          return 10;
    }
    
    template<typename T>
    int RankMat(T const& Input, typename std::enable_if<(not is_ring_field<T>::value),T>::type* = 0)
    {
          return 20;
    }
    

    或者这个:

    template<typename T, typename TT = is_ring_field<T>>
    int RankMat(T const& Input)
    {
          return TT::value ? 10 : 20;
    }
    

    【讨论】:

    • 实际上这不是允许在 sfinae 中生成软错误的唯一上下文...请参阅 thisthis。你提出的那个实际上是从 c++11 开始的,在函数模板参数不允许被默认之前......
    • 对。快速回答是个坏主意。我提供了错误的信息。这对我来说是一个教训。
    猜你喜欢
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 2011-08-26
    • 2014-10-06
    • 1970-01-01
    相关资源
    最近更新 更多