我正在尝试制作两个包含自定义结构的不同向量,但是当我尝试向向量添加元素时,它适用于" deck"向量但引发了#34;玩家的错误#34;向量。我是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 :(得分: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));
答案 1 :(得分:1)
我不知道您的编译选项,但警告
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|
让我得出结论:c ++ 11(初始化列表)未启用。
但不是很少,代码将无法编译,因为初始化列表显然无法处理参数的默认值。在这种情况下,问题的根源是行:
int default_bet = 5;
删除默认值并启用c ++ 11,然后您的代码将起作用。
答案 2 :(得分:1)
问题根本与矢量无关,但可以通过以下方式更简单地看到:
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 {{1}中看到}不是聚合,但在C ++ 14中player
是一个聚合。
使用g ++进行测试,我发现g ++ 5.1正确地实现了这种行为 - 代码被player
拒绝并被-std=c++11
接受。但是,g ++ 4.9.2拒绝使用-std=c++14
的代码,因此这将是该版本的g ++中的编译器错误。
结论:如果您可以访问g ++ 5.1(或其他正确实现C ++ 14的编译器),那么解决方案是在编译代码时使用-std=c++14
标志。否则你将不得不提出一些丑陋的解决方法。