如何从非常数初始化常量?

时间:2011-08-17 18:01:26

标签: c++ const

如何初始化常量以将其用作bitset对象的大小参数,以便从非常量变量获取其值?

int x=2;
int y=Some_Function(x);
const int z=y;
bitset<z> b;

3 个答案:

答案 0 :(得分:8)

你不能这样做,因为数组的大小或std::bitset的模板参数必须是编译时常量,而不是运行时常量。 const必须在编译时自己知道,以便用作数组大小,或在std::bitset中。

int x = getSize();
const int y = x;  //ok - runtime const. y cannot be changed; x can be changed!
int a[y];         //error in ISO C++ - y is not known at compile time!
std::bitset<y> b; //error in ISO C++ - y is not known at compile time!

const int z = 10; //ok - compile-time const. z cannot be changed!
int c[z];         //ok - z is known at compile time!
std::bitset<z> d; //ok - z is known at compile time!

上面的代码和注释是根据C ++ 98和C ++ 03制作的。

但是,在C ++ 11中,y将是编译时常量,并且涉及y的代码将编译如果 y被初始化为:

 const int y = getSize(); //i.e not using `x` to initialize it.

getSize()定义为:

 constexpr int getSize() { /*return some compile-time constant*/ }

关键字constexpr已添加到C ++ 11中以定义generalize constant expressions

答案 1 :(得分:2)

常量变量和编译时常量之间存在差异。比较:

int main(int argc, char* argv[])
{
  const int i = argc; // constant
}

此变量i与函数作用域一致,但在编译时它的值是未知的。

另一方面,以下两个是编译时常量:

const int a = 12;

int f(int n) { return 2 * n; }  // see below

const int b = f(6);

编译时都知道ab

只有编译时常量可以用作数组大小或模板参数! (模板本质上是代码生成机器,因此必须在编译最终程序之前生成代码。)

std::bitset<a> B1; // OK, same as std::bitset<12>
std::bitset<b> B2; // OK in C++11, not allowed in C++98/03

// but, in main() above:
std::bitset<i> B3; // Cannot do, we don't know i at compile-time!

请注意,在C ++ 98/03中,b实际上并未被正式识别为编译时常量。 C ++ 11通过允许f声明constexpr来修复此问题,这意味着它允许计算编译时常量表达式(如果它的所有参数本身都是常量)。

答案 2 :(得分:0)

让我们区分编译时常量和带有const的变量。你的是后者;只有前者可以作为数组大小(在C ++ 0之前)。