【问题标题】:How is "int main(){(([](){})());}" valid C++?“int main(){(([](){})());}”如何有效的 C++?
【发布时间】:2012-11-16 04:46:06
【问题描述】:

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

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

将其重新格式化,使其更具可读性:

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

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

  • 它看起来不像函数指针语法。
  • 这不可能是某种运算符重载技巧。代码按原样编译。

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

JavascriptC function pointers 之外,我从未见过任何如此奇怪的有效代码。

有人可以解释一下这是有效的 C++ 吗?

【问题讨论】:

  • 嘿!那是我的。 "Don't sweat it. We have int main(){(([](){})());} which is valid C++"(11 月 9 日聊天)
  • 这是一个 c++11 lambda 闭包
  • @Mysticial - 这段代码让你感到迷惑,因为它没用。如果这个 lambda 可以做某事,你会发现它的语法类似于函数指针(与函数指针密切相关)。
  • @Mysticial - “6 年的 C++”—— lambdas 刚刚在 C++11 中添加,所以大约一年前没有人使用过它们。
  • 这里的网址很有趣:“how-is-int-main-valid-c”

标签: c++ c++11 lambda syntax


【解决方案1】:

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

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

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

然后,() 在第一个包装括号之后调用(空)lambda。我们现在在([](){})()

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

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


† 至少在 C++ 中有 一些 极端情况,例如 T a_var; there's a difference between decltype(a_var) and decltype((a_var))

【讨论】:

  • @R.MartinhoFernandes:它仍然卡在某个人身上,所以我不得不去取回它。
  • 我会赞成正确提到在表达式周围添加 () 会改变语义的情况。但后来我想起这与问题无关,真的。不错的答案
  • 在最棘手的解析消歧的情况下,括号也改变了程序的含义:B foo(A()) foo 是一个函数(将一个指向函数的指针作为唯一参数并返回一个 B)而在B foo((A())) foo 中是一个 B 对象,它调用一个构造函数,该构造函数采用一个 A 对象(在这种情况下,该实例是一个匿名临时对象)。
  • @AdN:这不再是表达,而是声明。
  • @R.MartinhoFernandes 我认为 Ramon 认为您的意思是 lambda-dagger,它会刺伤返回类型。 (它通常被称为“箭头”,但我可以看到将-> 称为“匕首”)
猜你喜欢
  • 2016-01-05
  • 2018-03-16
  • 2012-03-10
  • 2011-06-26
  • 1970-01-01
  • 2020-03-01
  • 2013-11-04
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多