constexpr静态成员与变量的区别

3
我发现了一些C++11代码,看起来像这样:

// some_file.h
namespace blah {
  class X {
   public:
    constexpr const static std::initializer_list<uint64> SOME_LIST =
      {1,2,3};
  };
}

// some_file.cpp
#include "some_file.h"
namespace blah {
  constexpr const std::initializer_list<uint64> X::SOME_LIST;
}

这编译起来很顺利。我认为在cpp文件中定义是为了避免每个包含头文件的文件中都出现符号重复(如有错误,请指正)。

然后我尝试了以下操作:

// my_file.h
namespace bleh {
  constexpr const static char SOME_CONSTANT[] = "yay";
}

// my_file.cpp
#include "my_file.h"
namespace bleh {
  // if I add this or any other variation, compilation breaks!
  //constexpr const static char SOME_CONSTANT[];
}

如果我在.cpp文件中添加显式定义,则上述代码将无法工作。因此,我想知道:第二种情况是否存在符号重复?如果有,是否有一种方法可以定义不带封闭类的变量?


2
constexpr const X::SOME_LIST; 缺少类型说明符。您确定这是编译的代码吗? - typ1232
@typ1232 抱歉,我在编写代码时没有实际编译,但我正在查看一个可以编译的示例。 - Giovanni Botta
1个回答

2
static关键字在这里有两个不同的含义:
当您在文件范围(全局和/或命名空间作用域)声明变量或函数时,static关键字指定该变量或函数具有内部链接。当您声明一个变量时,变量具有静态持续性,并且编译器将其初始化为0,除非您指定其他值。
当您在类声明中声明数据成员时,static关键字指定该成员的一个副本由类的所有实例共享。必须在文件作用域定义静态数据成员。您可以将一个被声明为const static的整数数据成员初始化。
C++需要您在某处定义静态类成员,因为类符号是全局的(您的成员也是)。这不能在头文件中完成,因为会存在多重定义问题。
在第二种情况下,每个编译单元使用自己的变量,没有全局符号。

在第二种情况下,有没有一种方法可以拥有一个全局符号?我应该只是在那种情况下添加一个类来强制执行吗? - Giovanni Botta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接