我想使用类 namespace 中的常量作为静态数组的大小和另一个类中的模板参数。我有错误

// MS VS 2010 C++98
// A.h
class A
{
public:
 const static int someNumber;
};
// A.cpp
#include <A.h>
const int  A::someNumber = 5;

// B.h
#include <A.h>
class B
{
  std::bitset<A::someNumber> btst; // Error! C2975: '_Bits' : invalid template argument

  double control[A::someNumber];   // Error! C2466: cannot allocate an array of constant size 0
};

如何避免它们?

最佳答案

您的问题不是那么简单,因为如果将所有声明放在一个文件中,它将正确编译并运行。

但是只要看看编译器在编译B.h时会看到什么(假设它包含在main.cpp或B.cpp中):
#include "A.h":好的,它包含const static int someNumber; someNumber是一个const int,其值将在链接时给出
std::bitset<A::someNumber> btst:好的位集,其大小是A::someNumber,它声明为const int,直到这里都可以...但是哇,当时编译器不知道const的值!假设它是0
=>并且您会遇到两个错误,因为编译器无法知道A::someNumber的 future 值!

现在我们知道,修复很简单:只需在A.h中编写:

const static int someNumber = 5; // valid for a litteral const

因为现在编译器在编译时就知道A::someNumber的值,并且可以正确地编译包含B.h的文件。

编辑

您可能对用const static int someNumber = 5;编写A.h的想法感到害怕,因为它可能包含在许多编译单元中,并且您不想在许多单元中定义相同的常量。但实际上这不是问题:
  • 在编译时,编译器会在需要时随时使用A::someNumber的值。并且注意到,类A包含一个名为someNumber静态字段。
  • 在链接时使用
  • ,链接器确保A::someNumber仅存在一个实例。您可以通过打印来自不同编译单元的静态const字段的地址来控制它,并且您将获得相同的值……除非您的开发工具严重损坏!
  • 09-25 15:57