在C++中,({})被称为什么?

21
我刚刚读到这样的代码:
auto value = ({
  auto it = container.find(key);
  it != container.end() ? it->second : default_value;
});

这个 ({}) 叫什么?我觉得我以前从来没见过这个。

9
这是一个gcc的扩展,如果我没记错的话。不是标准的C++。 - Jarod42
1
对我来说无法编译,即使我为keycontainer添加了合理的定义。你能提供一个没有任何缺失部分的示例吗? - john
3
这是一个编译器扩展,详情请参考https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html。 - n. m. could be an AI
default 是一个关键字。即使移除了语句表达式,它怎么编译 it != container.end() ? it->second : default; - 273K
有趣的是,我们几天前还有一个 C 版本也在热门网络问题中出现:当 a 是一段代码块时使用逗号运算符 (a, b) - Peter Cordes
显示剩余2条评论
2个回答

29
这是一个gcc的扩展,所以不是标准的C++。
它是语句表达式
自从C++11以来,在大多数情况下,你可以使用立即调用的函数表达式(IIFE)与lambda代替。
auto value = [&](){
  auto it = container.find(key);
  return it != container.end() ? it->second : default_value;
}();

5
这与lambda函数仍然不同,因为在语句表达式中的返回语句会从封闭的函数返回,而不是从语句表达式返回。 - Daniel
@Daniel:同样地,对于break/continue也是如此... - Matthieu M.

11

即使在C89发布之前,gcc的作者们发明了一种称为“语句表达式”的扩展,它本应成为标准语言的一个有用部分。它采用一个由多个语句组成的复合语句,其中最后一个语句是一个表达式,并执行其中的所有内容,然后将最后一个表达式的值作为整个语句表达式的值。

虽然其他一些编译器具有支持这种gcc扩展的选项,但是标准不承认未被广泛使用的功能,再加上程序员对于标准不认可的功能的不愿使用,导致了一个持续几十年的“先有鸡还是先有蛋”的问题。


1
你本可以像Jarod一样提到一个完整的捕获lambda函数。 - Red.Wave
1
@Red.Wave C89也没有这些功能,哈哈 ;-p - SamB
@SamB 是的,但在2023年,lambda是一个众所周知的术语。而且提供的语法行为符合lambda的定义。某些无名之物已存在很多年了;但现在我们知道它的名字并应该拼写出来。 - Red.Wave
@Red.Wave:虽然它不等同于lambda,但是行为上有所不同。具体来说,流程控制语句(breakcontinuereturn)在两者之间是不同的,因为lambda创建了一个全新且独立的函数作用域,而语句表达式只是封闭函数作用域中的“又一个”语句。 - Matthieu M.
@MatthieuM。它符合lambda的基本定义。现代C++ lambda只是稍微受限制一些。 - Red.Wave
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接