Mic*_*ael 12 c++ templates compile-time-constant
我有以下非常简单的模板.据我所知,^不是指数运算符.现在我正在寻找一种计算这种能力的方法.互联网上有许多递归模板的例子.这不是太难.
但我想知道:在C++中实际上没有"内置"方法来在编译时计算它吗?
template <int DIM>
class BinIdx : Idx
{
static const int SIZE = 3 ^ DIM; // whoops, this is NOT an exponential operator!
}
Run Code Online (Sandbox Code Playgroud)
rig*_*old 10
如上所述,<<如果指数是2的幂,则可以使用.
否则,如果指数是非负整数,则可以编写类似于此的constexpr函数.
template<typename T, typename U>
auto constexpr pow(T base, U exponent) {
static_assert(std::is_integral<U>(), "exponent must be integral");
return exponent == 0 ? 1 : base * pow(base, exponent - 1);
}
Run Code Online (Sandbox Code Playgroud)
不过,对于大型指数和负指数,这显然会受到打击.
我并不完全清楚编译器在常量表达式中如何优化函数调用.这是针对指数为2的幂的情况的手动优化.这也将减少完成的递归量.
template<typename T>
bool constexpr is_power_of_two(T x) {
return (x != 0) && ((x & (x - 1)) == 0);
}
template<typename T, typename U>
auto constexpr pow(T base, U exponent) {
static_assert(std::is_integral<U>(), "exponent must be integral");
if (is_power_of_two(exponent)) {
return base << exponent;
}
return exponent == 0 ? 1 : base * pow(base, exponent - 1);
}
Run Code Online (Sandbox Code Playgroud)
还可以使用更有效的算法.但是,我不擅长计算机科学,所以我不知道如何实现它们.
作为elyse答案的补充,这里的递归深度为log(n):
template<typename T>
constexpr T sqr(T a) {
return a * a;
}
template<typename T>
constexpr T power(T a, std::size_t n) {
return n == 0 ? 1 : sqr(power(a, n / 2)) * (n % 2 == 0 ? 1 : a);
}
Run Code Online (Sandbox Code Playgroud)
不,没有通用的内置方法来计算值的幂。有pow标准库中的函数,您可以<<在特殊情况下使用移位运算符2^x。
这适用于您的情况 (*):
static const int SIZE = (1 << DIM);
Run Code Online (Sandbox Code Playgroud)
* =在我写下答案后,您将问题从 更新2^x为3^x。
对于另一个特殊情况 x^y,其中 x 和 y 是静态的,您可以编写一个长乘法:
const result int = x*x*x*x*x;
Run Code Online (Sandbox Code Playgroud)
您可以使用模板元编程.让我展示一下代码.
template <int A, int B>
struct get_power
{
static const int value = A * get_power<A, B - 1>::value;
};
template <int A>
struct get_power<A, 0>
{
static const int value = 1;
};
Run Code Online (Sandbox Code Playgroud)
用法:
std::cout << get_power<3, 3>::value << std::endl;
Run Code Online (Sandbox Code Playgroud)