我正在努力应对以下情况.
#include "systemc.h"
template<int maxval>
class Foo {
/* Error: calls to constructors and functions cannot be part of a constant expression */
sc_uint<int(log2(double(maxval)))> a;
...
};
int main() {
Foo<10> foo;
...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如上所述,模板化类'Foo'具有模板参数'maxval'.'Foo'还拥有一个成员,同样是一个模板化的类,它在模板参数中使用模板参数'maxval'和函数'log2'进行实例化.但是,所描述的代码将不起作用,因为例如函数调用不能是常量表达式的一部分.您是否认为有可能在编译期间评估例如log2(maxval)并将结果用于'Foo'中的其他模板参数?
谢谢你的帮助.(我正在使用GCC 4.1.2)
模板需要编译时值.该log2功能需要constexpr为此工作(事实并非如此).
你必须定义自己的constexpr功能.对于基数2的对数函数,如果需要整数(切除浮点部分),它可以工作:
constexpr int log2(int number, int acc = 0) {
return number <= 1 ? acc : log2(number / 2, acc + 1);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我没有注意到问题是GCC 4.1,它不支持constexpr.虽然如果您可以使用该选项,您应该尝试升级,但您也可以使用@ Florian的答案中提出的基于模板的解决方案.
编辑2:
如果您不想依赖Boost,可以使用以下基于模板的简单实现:
template<int V>
struct log2 {
static int const value = 1 + log2<V/2>::value;
};
template<>
struct log2<0> {};
template<>
struct log2<1> {
static int const value = 0;
};
Run Code Online (Sandbox Code Playgroud)
然后你会使用它log2<13>::value,这将导致3.
又一个编辑:
在constexpr上面的实现将返回0的0数和负数,这是一个错误.对数没有为零值或负值定义(在真实域中),因此可以调整函数以引发错误(因为它有点不可读,我为格式添加了一些换行符):
constexpr int log2(int number, int acc = 0) {
return number <= 0
? throw std::logic_error{"Logarithm of zero or negative number not allowed."}
: number == 1
? acc
: log2(number / 2, acc + 1);
}
Run Code Online (Sandbox Code Playgroud)