Conditional code depending on template parameters comparision

everybody! Want to make method compiling differently depending on template parameters.

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;
  }
...
};

But the code above calls block for prec==prec1 even for different precs.

Upvotes: 0

Views: 476

Answers (2)

O&#39;Neil
O&#39;Neil

Reputation: 3849

As already said, C++17's if constexpr is the best solution:

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;
}

If you're using C++11, you can use SFINAE with std::enable_if hidden in a REQUIRES macro:

#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;
}

Note that input parameter d is passed by const reference to avoid unnecessary copy.

Upvotes: 1

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154035

It seems you want to use something like

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

if constexpr was introduced with C++17.

Upvotes: 1

Related Questions