函数调用模板参数

che*_*002 3 c++ gcc

我正在努力应对以下情况.

#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)

Stj*_*rac 8

模板需要编译时值.该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上面的实现将返回00数和负数,这是一个错误.对数没有为零值或负值定义(在真实域中),因此可以调整函数以引发错误(因为它有点不可读,我为格式添加了一些换行符):

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)