我正在观看 Bjarne Stroustrup 关于 C++11 风格的主题演讲 (link) (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};
?即声明后的大括号是什么? 最佳答案
是的,你是对的。
可以从 int
初始化的任何类型。例如,如果您的 Gadget
类的构造函数采用 int
,或者采用可以直接从 int
初始化的内容,则可以编译代码。
这是统一的初始化语法。它消除了括号表示法的一些令人讨厌的问题,这些问题会使 C++ 编译器将以下内容解析为函数声明(而不是作为对象的初始化):
struct Widget { /* ... */ };
struct Gadget { Gadget(Widget const&) { /* ... */ } /* ... */ };
Gadget g(Widget()); // This is parsed a FUNCTION DECLARATION
在上面的例子中,意图程序员可能已经构建
g
类型的对象Gadget
和从临时Widget
对象初始化:然而,编译器会解析此作为函数的声明称为g
返回一个Gadget
和将不接受任何参数并返回 Widget
的(指向 a 的指针)作为其参数。这被称为 Most Vexing Parse 问题。请注意,使用大括号时不存在上述问题:
Gadget g{Widget{}}; // This could not be possibly parsed as a function declaration!
这很可能是因为您没有使用符合 C++11 的编译器。您应该使用一个,并使用
-std=c++11
或 -std=c++0x
编译标志来启用 C++11 支持。关于用大括号代替赋值运算符的 C++ 声明和实例化作用域变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16733394/