Ошибка множественных структурных векторов в C++

Я пытаюсь создать два разных вектора, содержащих пользовательские структуры, но когда я пытаюсь добавить элементы к векторам, это работает для вектора "колода", но выдает ошибку вектора "игроки". Я новичок в C++ и не могу понять, что не так.

Это ошибки, которые он выдает:

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|

error: no matching function for call to 'std::vector<BlackjackClass::player>::push_back(<brace-enclosed initializer list>)'|

Это код, который я использую:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class BlackjackClass {

    private:
        struct card
        {
                string label;
                int value;
                string suit;
        };
        vector<card> deck;

        struct player
        {
                string name;
                int bankroll;
                int default_bet = 5;
        };
        vector<player> players;

    public:
        BlackjackClass()
        {
            // Works
            deck.push_back({"Queen", 10, "Hearts"});
            // Doesn't Work
            players.push_back({"Jim", 500, 5});

        }
};

int main()
{
    BlackjackClass Blackjack;
}

3 ответа

Решение

Это потому, что у вас есть значение по умолчанию для default_bet. Удалите его, и он будет работать или строить объект явно вместо списка инициализатора

    struct player
    {
            string name;
            int bankroll;
            int default_bet = 5;
            player(string name_, int bankroll_, int default_bet_)
            {
                name=name_;
                bankroll=bankroll_;
                default_bet_=default_bet_;
            }
    };


    players.push_back(player("Jim", 500, 5));

Проблема не связана с векторами вообще, но может быть замечена более просто следующим:

card c { "Queen", 10, "Hearts" };    // OK     (g++ -std=c++11)
player p { "Jim", 500, 5 };          // Not OK (g++ -std=c++11)

Существует вещь, называемая агрегатной инициализацией, при которой агрегат может быть инициализирован из заключенного в скобки списка инициализаторов, минуя конструктор. Но неагрегаты не имеют этого; они могут быть инициализированы только их конструктором. И то и другое player а также card есть неявно сгенерированные конструкторы по умолчанию без аргументов, и все.


Ваш компилятор, кажется, лечит card как совокупность, но player не.

В C++11 это правильно, из N3337 [dcl.init.aggr]/1:

Агрегат - это массив или класс (раздел 9) без предоставленных пользователем конструкторов (12.1), без инициализаторов фигурных или равных скобок для нестатических элементов данных (9.2), без закрытых или защищенных нестатических элементов данных (Пункт 11), нет базовых классов (пункт 10) и нет виртуальных функций (10.3).

Однако в C++14 (N3936) это было изменено на:

Агрегат - это массив или класс (раздел 9) без предоставленных пользователем конструкторов (12.1), без закрытых или защищенных нестатических элементов данных (пункт 11), без базовых классов (пункт 10) и без виртуальных функций (10.3).

= 5 в вашем коде есть инициализатор скобки или равный для нестатического члена данных, так что мы можем видеть это в C++11 player не агрегат, но в C++ 14 player это совокупность.

Тестируя с g ++, я обнаружил, что g++ 5.1 правильно реализует это поведение - код отклоняется с -std=c++11 и приняты с -std=c++14, Однако g++ 4.9.2 отклоняет код с -std=c++14, так что это будет ошибка компилятора в этой версии g ++.


Вывод: если у вас есть доступ к g++ 5.1 (или другому компилятору, который правильно реализует C++14), тогда решением будет использование -std=c++14 флаг при компиляции вашего кода. В противном случае вам придется использовать некоторые уродливые обходные пути.

Я не знаю ваши параметры компиляции, но предупреждение

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|

приводит меня к выводу, что C++11 (списки инициализаторов) не включен.

Но, тем не менее, код не будет компилироваться, поскольку списки инициализаторов не могут обрабатывать значения параметров по умолчанию. В этом случае источником проблемы является строка:

int default_bet = 5;

удалите значение по умолчанию и включите C++11, тогда ваш код будет работать.

Другие вопросы по тегам