条件代码依赖于模板参数比较

Conditional code depending on template parameters comparision

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

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 调用块。

您似乎想使用类似

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

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

如前所述,C++17 的 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,则可以使用隐藏在 REQUIRES 宏中的 std::enable_if SFINAE:

#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 引用传递以避免不必要的复制。