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

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

本文关键字:简单 声明 构造函数 c++ 可以使 语法 初始化 我可以      更新时间:2023-10-16

假设我有以下代码:

#include <vector>
struct Foo
{
    int tag = 0;
    std::function<void ()> code;
};
int main()
{
   std::vector<Foo> v;
}

现在我想添加一个新的Foo项到具有特定tagcode 的向量中,而不需要显式地创建一个临时项。这意味着我必须为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不是聚合,大括号或相等初始化式的存在阻止了它成为聚合。

然而,这个规则在c++ 14中被改变了,所以如果你用-std=c++14(或者任何你的编译器的等效设置)编译你的代码,Foo将是一个聚合,你的代码将成功编译。

现场演示

对于c++ 11编译器,必须删除初始化式(这会使Foo成为聚合),或者提供两个参数的构造函数。