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};?即声明后的大括号是什么?
  • (可能太宽泛了,但是)为什么编译器不能将大括号识别为有效语法?
4

1 回答 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

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

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

Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!

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

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

于 2013-05-24T11:10:56.863 回答