条件代码依赖于模板参数比较
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;
}
请注意,输入参数 d
由 const
引用传递以避免不必要的复制。
大家好!想要根据模板参数对方法进行不同的编译。
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;
}
请注意,输入参数 d
由 const
引用传递以避免不必要的复制。