【问题标题】:What's actually going on in this AnonymousClass(variable) declaration?这个 AnonymousClass(variable) 声明中到底发生了什么?
【发布时间】:2011-06-14 10:04:47
【问题描述】:

尝试编译:

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 的Q10.2Q10.21 中描述的案例),但我不熟悉这个。

【问题讨论】:

  • 啊,是的,符号名称周围的括号显然是合法的,就像函数指针声明的典型情况一样。耶。
  • 您还可以通过将AnonymousClass(x) 强制为子表达式来防止AnonymousClass(x) 被视为x 的定义。例如(void) AnonymousClass(x);。从语法上讲,这不可能是一个定义,因此它是一个表达式语句,它使用单参数构造函数创建一个对象,然后将其销毁。

标签: c++


【解决方案1】:
AnonymousClass(x);

它定义了AnonymousClass 类型的变量x。这就是您收到重新定义错误的原因,因为 x 已被声明为 int

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

AnonymousClass(x);
AnonymousClass((x));
AnonymousClass(((x)));
AnonymousClass((((x))));
//and so on

它们都与:

AnonymousClass x;

演示:http://www.ideone.com/QnRKH


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

int x = 10;
f(A(x));        //1 - () is needed
f(A((((x)))));  //2 - extra () are superfluous

12 都调用一个函数 f 传递一个 A 类型的对象:

但同样,额外的括号在2行仍然是多余的。

【讨论】:

  • 好的,谢谢。除了声明函数指针之外,允许在声明的名称周围使用括号是否有用?
  • @jamesdlin:正如我所说,声明变量时括号是多余的。但是在声明函数指针时,它们并不是多余的;那时需要它。 A (*x)()A *x() 的含义不同。前者声明一个函数指针,后者是一个函数声明(原型)。
  • @Nawaz:我上面的评论询问它们是否对函数指针以外的任何其他有用。
  • @jamesdlin:我认为,superfluous 这个词解释了它在声明变量时没有用。相反,它增加了混乱。
  • @jamesdlin:括号也用于声明数组引用和指针。例如,AnonymousClass *ptr[3] 的类型与 AnonymousClass (*ptr)[3] 不同。对于特殊情况,这真的不是允许奇怪的语法的情况——有一个通用语法恰好是简单类型的奇怪(因为它在表达式中的含义似乎模棱两可,即构造一个带有 1 arg 的临时)。
【解决方案2】:

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

AnonymousClass myclass(x);

你也可以写...

AnonymousClass (myclass)(x);

所以你的代码行结果如下:

AnonymousClass (x);

或更常见的:

AnonymousClass x;

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

【讨论】:

  • 它们不仅仅用于分组。你不能随便加括号。类型周围的括号和带有关键字的括号具有特殊含义。您不能在关键字本身等周围添加括号。我真的很想知道为什么声明中的变量名周围都允许使用括号。
  • 在类型周围添加括号是不同的,因为这将被解释为强制转换。在关键字周围它们没有任何意义,但在实际(变量名称)周围它们对逻辑分组有意义(参见 Nawaz 的回答;例如,告诉编译器 * 所属的位置)。
【解决方案3】:

为避免此类错误,只需记住一条规则:如果您声明一个带有一个参数的匿名对象,只需将其放入一对括号中!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多