条件代码取决于模板参数的比较

时间:2018-01-29 06:38:55

标签: c++ templates conditional-compilation

大家好!想要根据模板参数进行不同的方法编译。

template <unsigned long prec> class DFixed {
public:
  unsigned long val;
...
  template <unsigned long prec1> DFixed<prec> &operator-=(DFixed<prec1> d) {
    #if prec==prec1
    val -= d.val;
    #elif prec<prec1
    val -= d.val/(prec1/prec);
    #else
    val -= d.val*(prec/prec1);
    #endif
    return *this;
  }
...
};

但是上面的代码甚至针对不同的prec来调用prec == prec1的块。

2 个答案:

答案 0 :(得分:1)

似乎你想要使用像

这样的东西
if constexpr (prec == prec1) {
    // one branch
}
else {
    // other branch
}

if constexpr是在C ++ 17中引入的。

答案 1 :(得分:1)

如上所述,C ++ 17&#39; if constexpr是最佳解决方案:

template <unsigned long prec1>
DFixed & operator-=(DFixed<prec1> d) {
    if constexpr (prec==prec1)
        val -= d.val;
    else if constexpr (prec<prec1)
        val -= d.val/(prec1/prec);
    else
        val -= d.val*(prec/prec1);

    return *this;
}

如果您正在使用C ++ 11,则可以使用SFINAE并将std::enable_if隐藏在REQUIRES宏中:

#define REQUIRES(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
template <unsigned long prec1, REQUIRES(prec==prec1)>
DFixed & operator-=(DFixed<prec1> const & d) {
    val -= d.val;
    return *this;
}
template <unsigned long prec1, REQUIRES(prec<prec1)>
DFixed & operator-=(DFixed<prec1> const & d) {
    val -= d.val/(prec1/prec);
    return *this;
}
template <unsigned long prec1, REQUIRES(prec>prec1)>
DFixed & operator-=(DFixed<prec1> const & d) {
    val -= d.val*(prec/prec1);
    return *this;
}

请注意,输入参数dconst引用传递,以避免不必要的复制。