我可以使用 C++11 大括号初始化语法来避免为简单聚合声明平凡的构造函数吗?

Can I use the C++11 brace initialization syntax to avoid declaring trivial constructors for simple aggregates?

假设我有以下代码:

#include <vector>

struct Foo
{
    int tag = 0;
    std::function<void ()> code;
};

int main()
{
   std::vector<Foo> v;
}

现在我想用特定的 tagcode 添加一个新的 Foo 项到向量中,而不用 显式创建暂时的。这意味着我必须为 Foo:

添加构造函数
struct Foo
{
    inline Foo(int t, std::function<void ()> c): tag(t), code(c) {}

    int tag = 0;
    std::function<void ()> code;
};

现在我可以使用 emplace_back:

v.emplace_back(0, [](){});

但是当我不得不再次执行此操作时 - 第 100 次 - 使用新创建的结构,我想:我不能使用大括号初始值设定项吗?像这样:

#include <vector>

struct Foo
{
   int tag = 0;
   std::function<void ()> code;
};

int main()
{
   std::vector<Foo> v;
   v.push_back(Foo{ 0, [](){} });
}

这给了我一个编译错误(无法从 'initializer-list' 转换为 'Foo'),但我希望这可以完成,我只是语法错误。

在 C++11 中,您不能在 struct 中使用 聚合初始值设定项,因为您使用了 等值初始值设定项 对于非静态成员 tag。删除 = 0 部分,它将起作用:

#include <vector>
#include <functional>

struct Foo
{
   int tag;
   std::function<void ()> code;
};

int main()
{
   std::vector<Foo> v;
   v.push_back(Foo{ 0, [](){} });
}

根据 C++11 标准,Foo 不是聚合,brace-or-equal-initializer 的存在阻止它成为一个聚合.

但是,this rule was changed for C++14,因此如果您使用 -std=c++14(或任何编译器的等效设置)编译代码,Foo 将是一个聚合,并且您的代码将编译成功。

Live demo

对于 C++11 编译器,您必须删除初始化程序,这将使 Foo 成为聚合,或者提供一个双参数构造函数。