3
#include <iostream>
using namespace std;

struct test
{
   int factorX;
   double coefficient;
};

int main()
{
   test firstTest = {1, 7.5}; //that's ok

   test *secondTest = new test;
   *secondTest = {8, 55.2}; // issue a compiler warning

}

我不明白为什么编译器会发出以下警告:

test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]

我知道在 C++11 中我可以省略赋值运算符,但事实并非如此。我正在使用 g++ 4.7.2。

4

3 回答 3

5

你的test结构是一个聚合体。虽然C++98 支持使用大括号语法初始化聚合,但不支持赋值。

在这里,真正发生的是编译器调用隐式生成的移动赋值运算符,该运算符将 atest&&作为其输入。为了使这个调用合法,编译器必须通过从它构造一个临时变量转换{8, 55.2}为一个实例,然后从这个临时test变量移动分配。*secondTest

此行为仅在 C++11 中受支持,这就是编译器告诉您必须使用该-std=c++11选项进行编译的原因。

于 2013-03-20T12:56:46.873 回答
2

因为第一个是初始化,第二个是赋值。您可以在 C++98 中以这种方式初始化简单结构,但不能赋值。

8.5.1/1

聚合是一个数组或一个类(第 9 条),没有用户声明的构造函数(12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3)。

8.5.1/2

当一个聚合被初始化时,初始化器可以包含一个初始化器子句,该子句由一个用大括号括起来的逗号分隔的初始化器子句列表组成,用于聚合的成员,以递增的下标或成员顺序编写。

但是类的第二次构造调用operator =,由于您没有用户定义的副本 c-tor,因此将调用默认的副本 c-tor,在 C++11 中使用表达式 in{}可以构造所需类型的对象,但在 C++ 中不行98.

于 2013-03-20T12:55:35.193 回答
1

错误信息告诉你你需要做什么,你需要在编译你的程序时添加-std=c++11-std=gnu++11到命令行。这是一个 C++11 特性,你必须启用它:

 test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
                                                                           ^^^^^^^^^     ^^^^^^^^^^^

正如安迪所说,在从创建的临时对象上使用隐式生成的移动函数是 C++11 的一个特性{8, 55.2},这就是你在第二种情况下所拥有的。

于 2013-03-20T12:55:45.583 回答