我刚刚发现以下内容无效。
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
初始化它的最佳位置在哪里?
我刚刚发现以下内容无效。
//Header File
class test
{
const static char array[] = { '1', '2', '3' };
};
初始化它的最佳位置在哪里?
最好的地方是在源文件中
// Header file
class test
{
const static char array[];
};
// Source file
const char test::array[] = {'1','2','3'};
您可以像尝试做的那样在类声明中初始化整数类型;所有其他类型都必须在类声明之外初始化,并且只初始化一次。
您始终可以执行以下操作:
class test {
static const char array(int index) {
static const char a[] = {'1','2','3'};
return a[index];
}
};
关于这个范例的一些好处:
//Header File
class test
{
const static char array[];
};
// .cpp
const char test::array[] = { '1', '2', '3' };
现在,在 C++17 中,您可以使用内联变量
一个简单的静态数据成员(N4424):
struct WithStaticDataMember { // This is a definition, no outofline definition is required. static inline constexpr const char *kFoo = "foo bar"; };
在您的示例中:
//Header File
class test
{
inline constexpr static char array[] = { '1', '2', '3' };
};
应该可以工作
即使在constexpr
C++11 中,您也必须在标头上定义值
如果您使用constexpr
而不是const
,那么这个答案表明您不仅可以而且必须在标头上定义,即使在 C++11 中:
#include <cassert>
struct MyClass {
static constexpr int is[] = {1, 2, 3};
static constexpr int i = 1;
};
// TODO is this ever mandatory? Create example that fails on -std=c++11.
// Pretty sure never mandatory in C++17 https://stackoverflow.com/a/40959093/895245
// constexpr int MyClass::is[];
int main (void) {
assert(MyClass::is[0] == 1);
assert(&MyClass::is[0] == &MyClass::is[1] - 1);
assert(MyClass::i == 1);
assert(&MyClass::i == &MyClass::i);
}
编译并运行:
g++-10 -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
相反,如果您尝试:
struct MyClass {
static constexpr int is[];
};
constexpr int MyClass::is[] = {1, 2, 3};
编译失败:
main.cpp:4:26: error: ‘constexpr’ static data member ‘is’ must have an initializer
在 Ubuntu 20.04 上测试。
这是对系统的一种滥用,但如果你真的想在头文件中定义它(并且你没有 C++17),你可以这样做。它不是静态成员,而是一个常量,只占用每个编译单元(而不是每个类实例)的存储空间:
(将所有这些代码放在头文件中。)
namespace {
const char test_init_array[] = {'1', '2', '3'};
}
class test {
public:
const char * const array;
test() : array(test_init_array) {}
};