C++ 为什么需要在初始化时指定外部/静态变量的类型?

C++ 为什么需要在初始化时指定外部/静态变量的类型?,c++,static,extern,C++,Static,Extern,我不理解在初始化时需要指定外部/静态变量的类型。例如: struct Test{ static int i; }; Test::i = 2; //error int Test::i = 2; //ok 编译器不知道我是int类型吗?这只是编译器的一个特殊性,还是为什么需要类型为、、int“的规范 我不理解在初始化时需要指定外部/静态变量的类型 因为语言设计人员选择对变量声明和定义使用相同的语法。该语法包括类型名称。您可以正确地认为,在某些情况下,该类型名称是多余的。但允许您忽略它可能会有

我不理解在初始化时需要指定外部/静态变量的类型。例如:

struct Test{
 static int i;
};
 Test::i = 2; //error
 int Test::i = 2; //ok
编译器不知道我是int类型吗?这只是编译器的一个特殊性,还是为什么需要类型为、、int“的规范

我不理解在初始化时需要指定外部/静态变量的类型

因为语言设计人员选择对变量声明和定义使用相同的语法。该语法包括类型名称。您可以正确地认为,在某些情况下,该类型名称是多余的。但允许您忽略它可能会有点混淆:它看起来像一个赋值,而不是定义

编译器不知道我是int类型吗

仅当变量已声明时。对于这样的静态成员,情况必须如此,但对于全局变量,情况不一定如此。您可以在一个源文件中声明它:

extern int i;
用另一种方式来定义它

int i = 42;

没有使声明对定义可用。

这是一个基本语法问题

一个C++文件由一系列声明组成。变量声明的基本语法类似:

类型
标识符
初始值设定项
opt

我省略了很多细节,但这是基本思想:文件范围中的内容必须是声明,变量声明必须以类型名称开头

如果开头没有类型的名称,您就有了一个简单的赋值语句——但这些语句只允许在函数内部使用,而不是像您在这里尝试的那样在文件范围内使用。

这个“限制”可以简化为简单的语法:语句

Test::i = 2; //error

是一个由赋值表达式组成的表达式语句。无论实体
Test::i
是什么,它都不会被实际解析为声明,调整语法以涵盖这一点将是极其复杂的,并且没有任何好处。

下面是一个有效的、可运行的代码示例,它将成为如果在整数
N::X::i
的定义中没有指定类型,则可以使用结构的消歧
struct
,但是没有任何等效的方法可以强制
int X::i
定义在您建议的语法下与
struct
不匹配

#include <iostream>

namespace N
{
  struct X
  {
    static int i;
    struct i { int n_; };
  };
}

int n = 2;

namespace N
{
  int X::i (n);   // take int out and under current C++ rules
                  // it will be equivalent to the next line
                  // (which is equivalent to struct X::i n; btw)
  struct X::i (n); // but under your proposed rules, ambiguous
}

int main()
{
    std::cout << N::n.n_ << ' ' << N::X::i << '\n';
}
#包括
名称空间N
{
结构X
{
静态int-i;
结构i{int n_;};
};
}
int n=2;
名称空间N
{
int x::i(n);//取int输出和当前C++规则
//它将相当于下一行
//(这相当于struct X::i n;顺便说一句)
struct X::i(n);//但在您提出的规则下,不明确
}
int main()
{

std::cout如果你能举出它会引起的歧义,这个答案会更加有力(这不能通过观察它是出现在函数内部还是外部来消除歧义)。@TonyD现在想不出任何简单而有说服力的例子,所以我现在就把它从答案中去掉。确切地说,
X::I{n}
如果不是整数的定义,也可以解释为(
struct
X::i
命名为
n
(可以接受多余的括号,这导致了最麻烦的解析问题)…但是你在那里使用了大括号,所以§8.3/6中的规则不适用。你是说
X::i(n)
?@Columbo:哦,是的-在我的电视上打字(HTPC设置)使用该死的日文键盘,字体太小,看不出有什么区别-谢谢。干杯。@Columbo:对不起-我的第一条评论/回复不应该说是全局的-当然是在名称空间N中。。。。