2015-11-05 5 views
4

Я пытаюсь создать два разных вектора, содержащих настраиваемые структуры, но когда я пытаюсь добавить элементы к векторам, которые он работает для вектора «колода», но выдает ошибку «игроков». Я новичок в 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; 
} 
+0

Глупый вопрос, но используете ли вы -std = C++ 11? – desu

+0

Я повернул -std = C++ 11, и это избавилось от предупреждения, но я все еще получаю вторую ошибку. –

+0

@ Karl-scmaltz вы пытались создать объект карты, а затем push_back? – desu

ответ

1

Это потому, что у вас есть значение по умолчанию для 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)); 
+0

И/или использовать конструктор. –

1

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

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

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

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

int default_bet = 5; 

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

1

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

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

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


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

В С ++ 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 ++.


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

Смежные вопросы