14

假设我有以下代码:

#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'),但我希望这可以完成,我只是语法错误。

4

2 回答 2

14

在 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, [](){} });
}
于 2015-06-07T17:44:38.657 回答
9

根据 C++11 标准,Foo它不是一个聚合,大括号或相等初始化器的存在阻止它成为一个。

但是,此规则已针对 C++14 进行了更改,因此如果您使用-std=c++14(或任何您的编译器的等效设置)编译代码,Foo则将是一个聚合,并且您的代码将成功编译。

现场演示

对于 C++11 编译器,您必须删除将进行Foo聚合的初始化程序,或者提供两个参数的构造函数。

于 2015-06-07T17:47:52.967 回答