我正在观看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};
?也就是说,声明后面的花括号是什么? - (可能太宽泛了,但是)为什么编译器不能将花括号识别为有效语法?
我假设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
的函数(指针指向a)。这就是所谓的最令人烦恼的解析问题。
注意,当使用大括号时,上面的问题不存在:
Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!
(可能太宽泛了,但是)为什么编译器不能将花括号识别为有效语法?
这很可能是因为您没有使用兼容c++ 11的编译器。您应该使用一个,并使用-std=c++11
或-std=c++0x
编译标志来启用c++ 11支持。