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