基本的 C++ 声明语法不是简单的从左到右的<type> <identifier>
语法。
如果这是 C++ 的语法,那么,例如,声明一个整数数组将使用类型int[]
后跟标识符来完成:
int[] foo
声明一个函数意味着编写一个函数类型,例如int()
后跟一个标识符:
int() foo;
取而代之的是,继承自 C 的 C++ 语法是一种称为“声明模仿使用”的风格
<type_identifier> <expression>;
声明中的表达式看起来像是您可以使用声明的实体的一种方式,并且这种用法将产生指定的类型。
例子:
int i; // now the expression i has the type int
int (ii); // now the expression (ii) has the type int, and so ii has the same type
int j(); // now the expression j() has type int, and therefore j has a function type
int k[3]; // now the expression k[3] has type int, and therefore k has an array type
int (*l)(); // the expression (*l)() has type int, and therefore (*l) has a function type, therefore l has a pointer-to-function type.
依此类推,涉及数组索引运算符、函数调用运算符、parens、解引用运算符、按位与运算符的任意复杂性,可能还有一些我不记得了。此外, const 和 volatile 可以在不同的地方加入。
更糟糕的是,声明语法可能会与初始化程序的语法发生奇怪的交互。例如,“最令人烦恼的解析”是一种情况,即初始化程序中的括号与声明函数类型所涉及的括号混淆。parens 是类型表达式的一部分还是初始化程序的一部分取决于其中使用的名称碰巧是什么:
struct bar {};
int baz() { return 1; }
int foo(bar()); // declaration of function (most vexing parse)
int foo2(baz()); // declaration of variable (initialized with baz())
当然还有其他人提到的问题;typedefs/类型别名、宏、嵌套声明、多重声明等。