C++多个结构体向量错误

4

我正在尝试创建两个包含自定义结构的不同向量,但当我尝试向这些向量添加元素时,"deck" 向量可以正常工作,而 "players" 向量会抛出错误。我是 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;
}

愚蠢的问题,但是你是否正在使用-std=c++11? - desu
我打开了-std=c++11,消除了警告,但我仍然收到第二个错误。 - keerl
@Karl-scmaltz 你尝试创建卡片对象并 push_back 吗? - desu
这个网站http://en.cppreference.com/w/cpp/language/aggregate_initialization可能会有所帮助。 - 001
在这种情况下,emplace_back() 似乎更能表达您的意图:players.emplace_back("Jim"s, 500, 5); - cdonat
3个回答

2
问题与向量无关,可以更简单地通过以下方式展示:
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`标志。否则,您必须使用一些丑陋的解决方法。

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));

可以使用构造函数。 - Neil Kirk

1
我不知道你的编译选项,但是警告提示。
warning: extended initializer lists only available with -std=c++11 or -std=gnu++11|

这让我得出结论,c++11(初始化列表)未启用。
但是,无论如何,代码都无法编译,因为初始化列表显然无法处理参数的默认值。在这种情况下,问题的根源是以下行:
int default_bet = 5;

移除默认值并启用C++11,然后您的代码将正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接