【发布时间】:2013-06-27 19:42:30
【问题描述】:
我有以下工作代码:
#include <string>
#include <iostream>
class A {
public:
const std::string test = "42";
//static const std::string test = "42"; // fails
};
int main(void){
A a;
std::cout << a.test << '\n';
}
是否有充分的理由无法将测试设为 static const ?我确实理解在 c++11 之前它受到标准的限制。我认为 c++11 引入了类内初始化以使其更友好一些。很长一段时间以来,我也没有这种语义可用于整数类型。
当然,它适用于const std::string A::test = "42";形式的类外初始化
我想,如果你可以使它成为非静态的,那么问题就出在两者之一。在类外范围内初始化它(通常consts 是在对象实例化期间创建的)。但是,如果您要创建一个独立于该类的任何其他成员的对象,我认为这不是问题。第二个是对静态成员有多个定义。例如。如果它被包含在几个.cpp 文件中,然后登陆到多个目标文件中,那么链接器在将这些对象链接在一起(例如,到一个可执行文件中)时会遇到麻烦,因为它们将包含相同符号的副本。依我的理解,这完全等同于 one 在 header 中的类声明下提供类外权限,然后在多个地方包含这个公共 header 的情况。我记得,这会导致链接器错误。
但是,现在处理这个问题的责任转移到了用户/程序员身上。如果一个人想要一个带有static 的库,他们需要提供一个类外定义,将其编译成一个单独的对象文件,然后将所有其他对象链接到这个对象,因此只有一个二进制副本符号的定义。
我阅读了Do we still need to separately define static members, even if they are initialised inside the class definition? 和Why can't I initialize non-const static member or static array in class? 中的答案。
我还是想知道:
- 只是一个标准的东西,还是背后有更深层次的推理?
- 这可以通过
constexpr和用户定义来解决吗 文字机制。 clang 和 g++ 都说变量不能有非文字类型。也许我可以做一个。 (也许出于某种原因这也是一个坏主意) - 链接器只包含一个
符号?因为它是
static const,所以应该是二进制精确的 不可变的副本。
如果我遗漏或误解了某些内容,请也发表评论。
【问题讨论】:
-
说到静态,只能在声明的时候初始化
const整型和枚举。 -
@juanchopanza 我知道。我认为在 c++11 中它可以被克服。
-
我认为您在 3. 中指出了问题之一。是的,它是可行的,但它需要这种情况是特殊情况,否则链接器只是不“喜欢”多个定义。
-
我从一开始就不明白这些限制的基本原理。多重定义的相同符号的问题也适用于模板实例化,因此链接器已经知道如何处理它(通过丢弃除一个之外的所有副本)。
-
@ondav 如果它的
const static真的是“多个”。不只是副本吗?为什么不选一个?我对链接器输入、地址翻译和其他东西不是很熟悉。也许有人知道为什么它这么难或被丢弃的想法。老实说,以前我认为这是类内初始化的问题而不是多个符号,但似乎并非如此。
标签: c++ c++11 in-class-initialization