我正在观看 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/

    10-16 07:29