“ int main(){((([](){})());}”如何有效C ++?


271

最近,我遇到了以下深奥的代码。

int main(){(([](){})());}

重新格式化,如下所示以使其更具可读性:

int main(){
    (([](){})());   //  Um... what?!?!
}

但是我无法理解(([](){})())有效代码的有效性。

  • 它看起来不像函数指针语法。
  • 这不可能是操作员重载的把戏。代码按原样编译。

Google在这种全符号搜索中并没有太大帮助。但是它可以在Visual Studio 2010中编译,但不输出任何内容。没有错误,也没有警告。因此,它看起来像有效的代码。

JavascriptC函数指针之外,我从未见过任何如此奇怪的有效代码。

有人可以解释这是如何有效的C ++吗?



31
这是一个c ++ 11 lambda闭包

7
@Mysticial-此代码使您感到迷惑,因为它没有用。如果此lambda可以执行某些操作,您将认识到它具有类似于函数指针的语法(与之密切相关)。
SChepurin

14
@Mysticial-“ C ++的6年”-lambdas只是在C ++ 11中添加的,因此一年左右之前没有人有使用它们的经验。
皮特·贝克尔

50
这里的URL很有趣:“ how-is-int-main-valid-c”
tckmn 2014年

Answers:


283

该代码实质上调用了一个空的lambda。

让我们从头开始:[](){}是一个空的lambda表达式

然后,在C和C ++中,您可以将表达式包装在括号中,它们的行为与没有它们的情况下完全一样,因此,这就是lambda周围的第一对括号。我们现在在([](){})

然后,()在第一次包装后,parens调用(空)lambda。我们现在在([](){})()

整个表达式再次包裹在括号中,我们得到(([](){})())

最后,;结束语句。我们到达(([](){})());


†有一些角落情况下,至少在C ++中,就像T a_var; 有之间的差异decltype(a_var)decltype((a_var))


7
错过了匕首。
R. Martinho Fernandes

33
@ R.MartinhoFernandes:它仍然被卡在某人中,所以我不得不去找它。
Xeo 2012年

1
我会为正确地提到在表达式周围加上()改变语义的情况而感到不满。但是后来我想起来,这确实与问题无关。好的答案
sehe 2012年

2
在最令人费解的parse歧义消除的情况下,括号也改变了程序的含义:B foo(A())foo是一个函数(将指向函数的指针作为唯一参数并返回B),而在B foo((A()))foo中,B是调用构造函数的B对象一个对象(在这种情况下,该实例为匿名临时对象)。
广告N

1
@AdN:不再是表达式,而是声明。
Xeo 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.