我想使用类 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字段的地址来控制它,并且您将获得相同的值……除非您的开发工具严重损坏!