C ++多结构向量错误

时间:2015-11-05 20:16:55

标签: c++ vector struct push-back

我正在尝试制作两个包含自定义结构的不同向量,但是当我尝试向向量添加元素时,它适用于" 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;
}

3 个答案:

答案 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)

有一个名为聚合初始化的东西,可以通过绕过构造函数从括号括起的初始化列表中初始化聚合。 但非聚合没有这个;它们只能由构造函数初始化。 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)。

代码中的= 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标志。否则你将不得不提出一些丑陋的解决方法。