【问题标题】:C++ Multiple Struct Vectors ErrorC++ 多结构向量错误
【发布时间】:2016-02-06 20:15:06
【问题描述】:

我正在尝试制作两个包含自定义结构的不同向量,但是当我尝试将元素添加到向量时,它适用于“甲板”向量,但会引发“玩家”向量的错误。我是 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 吗?
  • 我打开 -std=c++11 并消除了警告,但我仍然收到第二个错误。
  • @Karl-scmaltz 你试过创建卡片对象然后 push_back 吗?
  • 在这种情况下,emplace_back() 似乎更能说明您的意图:players.emplace_back("Jim"s, 500, 5);

标签: c++ vector struct push-back


【解决方案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));

【讨论】:

  • 和/或使用构造函数。
【解决方案2】:

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

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

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

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

int default_bet = 5;

去掉默认值并启用c++11,你的代码就可以工作了。

【讨论】:

    【解决方案3】:

    这个问题根本与向量无关,但可以通过以下方式更简单地看到:

    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 是一个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 标志。否则,您将不得不采用一些丑陋的解决方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-16
      • 2015-11-19
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 2012-10-16
      • 1970-01-01
      • 2018-09-10
      相关资源
      最近更新 更多