为什么 C++ 允许我们在声明变量时将变量名括在括号中?

Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

例如这样的声明:

int (x) = 0;

甚至这样:

int (((x))) = 0;

我偶然发现了这个,因为在我的代码中我碰巧有一个类似于下面的片段:

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}

显然我想构造对象 C,然后它会在其析构函数中做一些有用的事情。然而,碰巧编译器将 C (y); 视为类型为 C 的变量 y 的声明,因此它会打印有关 y 重新定义的错误。有趣的是,如果我将它写成 C (y).f () 或类似 C (static_cast<B*> (y)) 的形式,它将按预期进行编译。当然,最好的现代解决方法是在构造函数调用中使用 {}

所以我在那之后发现,可以声明像 int (x) = 0; 甚至 int (((x))) = 0; 这样的变量,但我从未见过有人实际使用这样的声明。所以我很感兴趣 - 这种可能性的目的是什么,因为现在我看到它只创建了类似于臭名昭著的案例 "most vexing parse" 而没有添加任何有用的东西?

分组。

作为一个特定的例子,假设您可以声明一个函数类型的变量,例如

int f(int);

现在,您将如何声明指向这样一个东西的指针?

int *f(int);

不行,不行!这被解释为返回 int* 的函数。您需要添加括号以使其以正确的方式解析:

int (*f)(int);

同样处理数组:

int *x[5];   // array of five int*
int (*x)[5]; // pointer to array of five int

通常允许在此类声明中使用圆括号,因为从语法的角度来看,声明总是如下所示:

<front type> <specification>;

例如,在下面的声明中:

int* p[2];

"front type" 是 int(不是 int*),"specification" 是 * p[2]

规则是您可以根据需要在 "specification" 部分使用任意数量的括号,因为它们有时不可避免地要消除歧义。例如:

int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints

指向数组的指针是一种罕见的情况,但是与指向函数的指针的情况相同:

int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int

这是对您问题的直接回答。如果您的问题是关于 C(y) 这样的陈述,那么:

  • 在整个表达式周围加上括号 - (C(y)) 你会得到你想要的
  • 这条语句除了创建一个临时对象外什么都不做,该对象在这条指令结束后就不再存在了(我希望这是你打算做的)。