2015-11-05 79 views
4

我想使两个不同的载体包含自定义结构,但是当我尝试向矢量添加元素时,它为“deck”向量工作,但抛出“players”向量的错误。我是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| 

使我得出结论,在C++ 11(初始化程序列表)未启用。

但是不是那么少,代码不会编译,因为初始化列表显然不能处理参数的默认值。在这种情况下,问题的根源是行:

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-初始化的事情封闭的初始化程序列表,绕过构造函数。 但非聚合不具备此;它们只能由其构造函数初始化。 playercard都隐式生成了不带参数的默认构造函数,就这些了。


你的编译器似乎是治疗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)。

的​​在代码是一个撑 - 或等于初始值设定为一个非静态数据成员,所以我们可以看到,在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标志。否则,你将不得不投入一些丑陋的解决方法。