#include <iostream>
struct B {
public:
static int const bsm1a{ 0xf };
};
int const B::bsm1a; // 1) Why is this NOT considered a redefinition?
// 2) What does this line actually do here?
int main()
{
std::cout << "Hello World!\n";
}#include <iostream>
struct B {
public:
static int const bsm1a{ 0xf };
static int const bsm1a; // Considered as a redefinition here and throws error C2086
};
int main()
{
std::cout << "Hello World!\n";
}我的问题(嵌入在代码中):
发布于 2020-10-03 20:38:00
,这就是我所收集的阅读C++标准的内容。如果我的解释是错误的,请纠正我。
在第一种情况下,情况相当有趣。这可以归结为declaration和definition在C++中的含义。如果深入研究C++标准,您将发现本主题的一个部分:
(§6.2)声明所宣布的每一实体也由该声明界定,除非: (§6.2.3)它在类定义中声明了一个非内联静态数据成员(11.4,11.4.8)
这告诉我们,行static int const bsm1a{ 0xf };不是一个定义,而是一个声明。
在类中定义static const数据成员是不允许的,因为当静态成员是类定义的一部分并被包含在多个不同的转换单元中时,它将违反“一个定义规则”(您现在可以使用inline变量后C++17进行定义)。所以以前的写法是
struct Foo {
public:
static const std::string str; //Declaration
};
const std::string Foo::str = "Hello World\n"; //Definition但是,允许在类定义中声明一个整数或枚举类型的static const变量(见第11.4.8.2.4节)。
如果非易失性非内联const静态数据成员为整型或枚举类型,则类定义中的声明可以指定大括号或等初始化项,其中作为赋值表达式的每个初始化器子句都是常量表达式。
static int const bsm1a{ 0xf };符合这个描述,因此它是允许的,但它仍然是一个声明。
此时,B::bsm1a是声明的,但没有定义。您可以给它一个整数或enum的值,因为编译器可以将它放入寄存器中,而不会实际为它分配内存。
#include <iostream>
struct B {
static const int bsm1a{0xf}; // Compiler keeps track of the 0xf internally
};
int main()
{
std::cout << &B::bsm1a << "\n"; //Whoops, this is not defined and there is no memory allocated to it, so taking its address is impossible (you'll get a linker error)
}当您注释掉std::cout并检查程序集时,没有任何参考到B::bsm1a。稍后编写int const B::bsm1a;时,这不是一个声明,而是一个定义。只有在此时,变量才会被定义,并将内存分配给它。检查以下代码的程序集时,您将看到"15“出现在最终程序集中,对&B::bsm1a的调用实际上解决了它的内存位置(movl $B::bsm1a, %esi)。
#include <iostream>
struct B {
static const int bsm1a{0xf};
};
const int B::bsm1a; // It is now defined and has memory assigned to it
int main()
{
std::cout << &B::bsm1a << "\n"; // We can now take its address
}在第二种情况下,您有另一个问题。
(第11.4.5节)成员不得在成员规格中声明两次,但 (§5.1)嵌套类或成员类模板可以声明,然后定义,(§5.2)枚举可以通过不透明枚举声明引入,然后用枚举说明符重新声明。
您根本不允许在类成员规范中重新声明它,除非它符合这两个条件。因此,例如,以下内容是合法的:
struct Foo
{
public:
struct X; // declaration
struct X; // redeclaration, allowed
};但是由于您的static const int不是这类类型中的一种,这是非法的。
https://stackoverflow.com/questions/64186005
复制相似问题