大家!想要根据模板参数使方法编译不同。
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 的 block。
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 与隐藏在 REQUIRES 宏中的
std::enable_if
一起使用:
#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;
}
请注意,输入参数
d
是通过const
引用传递的,以避免不必要的复制。
看来你想使用类似的东西
if constexpr (prec == prec1) {
// one branch
}
else {
// other branch
}
if constexpr
是随 C++17 引入的。
我还有另一个问题,我想根据模板值声明或不声明类参数:
template<unsigned int N,class T>
union Vec{
public:
T array[N];
struct{
//if N>0
T x;
//if N>1
T yn;
//if N>2
T z;
//if N>3
T w;
};
};
有人知道怎么做吗? 预先感谢。