使用花括号而不是赋值运算符声明和实例化局部变量的C++语法

13

我正在观看Bjarne Stroustrup关于C++11风格的主题演讲(链接)(00:35:30),但有些地方无法理解以下内容(代码来自幻灯片):

void f(int n, int x)
{
      Gadget g {n};
      // ...
      if (x<100) throw std::run_time_error{"Weird!"};
      if (x<200) return;
      // ...
}

我尝试使用结构体和对象编译此代码,但在两种情况下,编译器告诉我在声明Gadget g的末尾需要一个';',因此无法编译。

因此我的问题是:

  • 我是否正确地假设了g正在被实例化?
  • 为使此代码编译,Gadget必须是什么类型的对象?
  • 此行中有哪些概念:Gadget g {n}; ?即在声明之后的花括号是什么意思?
  • (可能太广泛了,但) 为什么编译器不将花括号识别为有效语法?

5
那是C++11的语法。您需要相关的编译器支持。 - juanchopanza
5
请使用符合 C++11 标准的编译器,并加入“-std=c++11”或“-std=c++0x”标记。 - Andy Prowl
1个回答

18

我是否正确地认为g正在被实例化?

是的,你是正确的。

为了使这段代码编译通过,Gadget必须是什么类型的对象?

任何可以从int初始化的类型。例如,如果你的Gadget类有一个接受int的构造函数,或者接受可以直接从int初始化的内容,那么这段代码就可以编译通过。

在这一行代码中,哪个概念起了作用:Gadget g {n};?也就是说,在声明后面的花括号是什么意思?

这是统一初始化语法。它消除了使用括号符号可能会产生的一些麻烦问题,这些问题会导致C++编译器将以下内容解析为函数声明(而不是对象的初始化):

struct Widget { /* ... */ };
struct Gadget { Gadget(Widget const&) { /* ... */ } /* ... */ };

Gadget g(Widget()); // This is parsed a FUNCTION DECLARATION

在上面的例子中,程序员的意图可能是构造一个类型为Gadget的对象g并从临时的Widget对象初始化它:然而,编译器将解析它作为声明一个名为g的函数,该函数返回一个Gadget并以一个(指向)不接受参数并返回Widget的函数作为其参数。这被称为最令人困惑的解析问题
请注意,使用大括号时不会出现上述问题:
Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!

“编译器为什么无法识别花括号作为有效的语法?”这可能是因为您没有使用符合C++11标准的编译器。您应该使用一个,并使用“-std=c++11”或“-std=c++0x”编译选项来启用C++11支持。

3
使用Gadget = int;可能是可以从一个整数初始化的最简单的类型 ;) - R. Martinho Fernandes

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