Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';在这个匿名类(变量)声明中到底发生了什么?_C++ - Fatal编程技术网

C++ 什么';在这个匿名类(变量)声明中到底发生了什么?

C++ 什么';在这个匿名类(变量)声明中到底发生了什么?,c++,C++,正在尝试编译: class AnonymousClass { public: AnonymousClass(int x) { } }; int main() { int x; AnonymousClass(x); return 0; } 从MSVC生成错误: foo.cpp(13) : error C2371: 'x' : redefinition; different basic types foo.cpp(12) : see d

正在尝试编译:

class AnonymousClass
{
public:
    AnonymousClass(int x)
    {
    }
};


int main()
{
    int x;
    AnonymousClass(x);
    return 0;
} 
从MSVC生成错误:

foo.cpp(13) : error C2371: 'x' : redefinition; different basic types
    foo.cpp(12) : see declaration of 'x'
foo.cpp(13) : error C2512: 'AnonymousClass' : no appropriate default constructor available
g++的错误消息类似:

foo.cpp: In function ‘int main()’:
foo.cpp:13: error: conflicting declaration ‘AnonymousClass x’
foo.cpp:12: error: ‘x’ has a previous declaration as ‘int x’
foo.cpp:12: warning: unused variable ‘x’

通过给
AnonymousClass
对象一个明确的名称,它很容易修复,但是这里发生了什么,为什么?我认为这是一种声明语法的怪异(就像在COMP.Lang.C++FAQ中描述的情况),但我不熟悉这个。

你缺少变量/对象的实际名称:

AnonymousClass myclass(x);
与其这样,不如写

AnonymousClass (myclass)(x);
因此,您的代码行会产生以下结果:

AnonymousClass (x);
或更常见的:

AnonymousClass x;
为什么会这样?括号仅用于逻辑分组(“什么属于一起?”)。唯一的区别是,它们被强制用于参数(即,您不能只编写
匿名类myclass x

它定义了一个
AnonymousClass
类型的变量
x
。这就是为什么会出现重新定义错误,因为
x
已声明为
int

括号是多余的。您可以添加更多大括号,如:

AnonymousClass(x);
AnonymousClass((x));
AnonymousClass(((x)));
AnonymousClass((((x))));
//and so on
它们都是相同的:

AnonymousClass x;
演示:


您可以使用语法
A(x)
创建匿名对象,尤其是在调用函数时:

int x = 10;
f(A(x));        //1 - () is needed
f(A((((x)))));  //2 - extra () are superfluous
1
2
调用函数
f
传递类型
a
的对象:


但是,第2行的额外括号仍然是多余的。为了避免这样的错误,请记住一条规则:如果您用一个参数声明匿名对象,只需将它放在一对括号中

一个类似的问题:啊,是的,在函数指针声明的典型情况下,符号名称周围的括号显然是合法的。是的。您还可以通过强制将
匿名类(x)
作为子表达式来防止将其视为
x
的定义。例如
(void)匿名类(x)。从语法上讲,这不可能是一个定义,因此它是一个表达式语句,使用一个参数构造函数创建一个对象,然后销毁它。相关:它们不仅仅用于分组。你不能随意添加括号。类型周围的括号和带有关键字的括号具有特殊含义。你不能在关键字周围加括号等等。我真的想知道为什么在声明中变量名周围都允许使用括号。在类型周围添加括号是不同的,因为这将被解释为强制转换。围绕关键字它们没有任何意义,但围绕实际(变量名)它们对逻辑分组有意义(参见Nawaz的答案;例如告诉编译器
*
属于何处)。好的,谢谢。除了声明函数指针之外,允许在声明的名称周围使用括号是否有用?@jamesdlin:正如我所说,在声明变量时,括号是多余的。但在声明函数指针时,它们并不是多余的;那是必要的
A(*x)(
A*x()
具有不同的含义。前者声明一个函数指针,后者是一个函数声明(原型)。@Nawaz:我上面的评论问它们是否对函数指针以外的任何东西有用。@jamesdlin:我想,多余这个词解释了它在声明变量时没有用。相反,它增加了混乱。@jamesdlin:paren还用于声明数组引用和指针。例如,
AnonymousClass*ptr[3]
的类型与
AnonymousClass(*ptr)[3]
不同。实际上,对于特殊情况,不允许使用奇怪的语法——对于简单类型,有一种通用语法恰好是奇怪的(因为它似乎与表达式中的含义不明确,即使用1 arg构造临时语法)。
int x = 10;
f(A(x));        //1 - () is needed
f(A((((x)))));  //2 - extra () are superfluous