C++ 为什么C++;是否允许我们在声明变量时将变量名括在括号中?
例如,声明如下:C++ 为什么C++;是否允许我们在声明变量时将变量名括在括号中?,c++,most-vexing-parse,C++,Most Vexing Parse,例如,声明如下: int (x) = 0; 甚至是: int (((x))) = 0; 我偶然发现了这一点,因为在我的代码中,我碰巧有一个类似于以下内容的片段: struct B { }; struct C { C (B *) {} void f () {}; }; int main() { B *y; C (y); } 显然,我想构造objectC,然后在其析构函数中执行一些有用的操作。然而,编译器处理C(y)作为类型为C的变量y的声明,因此它会打印一个关于y重新定义
int (x) = 0;
甚至是:
int (((x))) = 0;
我偶然发现了这一点,因为在我的代码中,我碰巧有一个类似于以下内容的片段:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
显然,我想构造objectC
,然后在其析构函数中执行一些有用的操作。然而,编译器处理C(y)
作为类型为C
的变量y
的声明,因此它会打印一个关于y
重新定义的错误。有趣的是,如果我把它写成C(y).f()
或者像C(static\u cast(y))
这样的东西,它就会按预期编译。当然,最好的现代解决方法是在构造函数调用中使用{}
正如我在那之后发现的,可以声明变量,比如int(x)=0代码>或甚至int((x))=0但我从未见过有人真正使用这样的声明。所以我很感兴趣——这种可能性的目的是什么,因为现在我看到它只创建了类似于臭名昭著的“最烦人的解析”的情况,并且没有添加任何有用的东西?分组
作为一个特殊的例子,假设可以声明一个函数类型的变量,例如
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
分组
作为一个特殊的例子,假设可以声明一个函数类型的变量,例如
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
(不是int*
),而“规格”是*p[2]
规则是,您可以根据需要在“规范”部分使用任意数量的括号,因为它们有时不可避免地会消除歧义。例如:
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))
,您将得到您想要的结果
- 这句话只不过是创建一个临时对象,它在本指令结束后停止存在(我希望这是您打算做的)
通常允许在此类声明中使用括号,因为从语法角度来看,声明通常如下所示:
<front type> <specification>;
“前端类型”是int
(不是int*
),而“规格”是*p[2]
规则是,您可以根据需要在“规范”部分使用任意数量的括号,因为它们有时不可避免地会消除歧义。例如:
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))
,您将得到您想要的结果
- 这句话只不过是创建一个临时对象,它在本指令结束后停止存在(我希望这是您打算做的)
这种可能性的“目的”可能是简化解析器。@GSerg的可能重复有趣的是,我的问题的文本如何回答您链接问题中的第二个答案中的问题,由于我提供了允许此类声明导致意外结果的示例:)陷入了这样的陷阱:不知道互斥被注释掉,然后意外地编写了错误的括号声明//std::mutex std::unique_锁(m_mutex);这种可能性的“目的”可能是简化解析器。@GSerg的可能重复有趣的是,我的问题的文本如何回答链接问题中的第二个答案中的问题,由于我提供了允许此类声明导致意外结果的示例:)陷入了这样的陷阱:不知道互斥被注释掉,然后意外地编写了错误的括号声明//std::mutex std::unique_锁(m_mutex);为了完成回答:不允许询问者询问的特定案例需要额外的特殊案例规则。当前对()
如何在类型中工作的定义在整个类型中是一致的。因此,特例适用于最麻烦的解析。这是因为初始化带有构造函数参数的变量的语法是后来添加的(我想是匆忙添加的吧?。@FISOCPP Well。对C++是继C.之后的。这个答案是否同样适用于C,而不仅仅是C++?“函数类型的变量”什么?!!为了完成回答:不允许询问者询问的特定案例需要额外的特殊案例规则。当前对()
如何在类型中工作的定义在整个类型中是一致的。因此,特例适用于最麻烦的解析。这是因为初始化带有构造函数参数的变量的语法是后来添加的(我想是匆忙添加的吧?。@FISOCPP Well。对C++是继C.之后的。这个答案是否同样适用于C,而不仅仅是C++?“函数类型的变量”什么?!!正如我提到的,最初它是在析构函数中做一些事情,我想当你有一些“链接”函数来设置一些参数和