C++ 多结构向量错误

C++ Multiple Struct Vectors Error

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

因为你有默认值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));

我不知道你的编译选项,但是警告

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

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

但无论如何,代码无法编译,因为初始化列表显然无法处理参数的默认值。在这种情况下,问题的根源是行:

int default_bet = 5;

删除默认值并启用 c++11,然后您的代码将运行。

这个问题根本与矢量无关,但可以通过以下更简单地看出:

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:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal- initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

但是在 C++14 (N3936) 中,这被更改为:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

代码中的 = 5 是非静态数据成员的 brace-or-equal-initializer,因此我们可以在 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 标志编译代码时。否则你将不得不采取一些丑陋的解决方法。