C++使用花括号而不是赋值运算符声明和实例化范围变量

svr*_*vrs 11 c++ scope c++11

我正在观看Bjarne Stroustrup在C++ 11 Style(链接)上的主题演讲(链接)(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;
      // ...
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用结构和对象编译此代码,但在这两种情况下,编译器都告诉我它期望';' 在声明结束时Gadget g并且不会编译.

因此,我的问题是:

  • 我是否正确地假设g正在实例化?
  • Gadget这个代码编译的对象必须是什么类型的对象?
  • 这条线上的概念是什么Gadget g {n};?即声明后的花括号是什么?
  • (可能过于宽泛,但是)为什么编译器不能将花括号识别为有效语法?

And*_*owl 16

我是否正确地假设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
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,程序员的意图可能是构造一个g类型的对象Gadget并从一个临时Widget对象初始化它:但是,编译器会将其解析为一个函数的声明,该函数g返回一个Gadget并将其作为参数a (指向a的函数)不接受任何参数并返回a的函数Widget.这被称为令人烦恼的解析问题.

请注意,使用大括号时,上述问题不存在:

Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!
Run Code Online (Sandbox Code Playgroud)

(可能过于宽泛,但是)为什么编译器不能将花括号识别为有效语法?

这很可能是因为您没有使用符合C++ 11的编译器.您应该使用一个,并使用-std=c++11-std=c++0x编译标志来启用C++ 11支持.

  • `using Gadget = int;`可能是可以从int初始化的simples类型;) (3认同)