Могу ли я использовать синтаксис инициализации С++ 11, чтобы избежать объявления тривиальных конструкторов для простых агрегатов?

Скажем, у меня есть следующий код:

#include <vector>

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

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

И теперь я хочу добавить новый элемент Foo в вектор с конкретными tag и code без, явно создавая временную. Это означает, что я должен добавить конструктор для 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, [](){});

Но когда мне пришлось это сделать снова - в сотый раз - с вновь созданной структурой, я подумал: не могу ли я использовать инициализатор скобок? Например:

#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'), но я надеюсь, что это можно сделать, и я только что получил синтаксис неправильно.

Ответы

Ответ 1

В С++ 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, [](){} });
}

Ответ 2

В соответствии со стандартом С++ 11, Foo не является агрегатом, наличие инициализатора скобок или равного не позволяет ему быть одним.

Однако это правило было изменено для С++ 14, поэтому, если вы скомпилируете свой код с помощью -std=c++14 (или независимо от его эквивалентной настройки компилятора), Foo будет агрегатом, и ваш код будет скомпилирован успешно.

Живая демонстрация

Для компилятора С++ 11 вы должны либо удалить инициализатор, который сделает Foo совокупность, либо предоставит конструктор двух аргументов.