简体   繁体   中英

C++ Multiple Struct Vectors Error

I am trying to make two different vectors containing custom structures but when I try to add elements to the vectors it works for the "deck" vector but throws an error of the "players" vector. I am new to C++ and cannot figure out what is wrong.

These are the errors it throws:

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

This is the code I am using:

#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;
}

It is because you have a default value for default_bet . Remove it and it will work or build the object explicitely instead of initializer list

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

I don't know your compile options, but the warning

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

leads me to the conclusion that the c++11 (initializer lists) is not enabled.

But non the less, the code won't compile, becaus initialzer lists apperently can't handle default values of parameters. In this case the source of the problem is the line:

int default_bet = 5;

remove the default value and enable c++11, then your code will work.

The problem isn't related to vectors at all but can be seen more simply by the following:

card c { "Queen", 10, "Hearts" };    // OK     (g++ -std=c++11)
player p { "Jim", 500, 5 };          // Not OK (g++ -std=c++11)

There is a thing called aggregate initialization whereby an aggregate may be initialized from a brace-enclosed initializer list, bypassing the constructor. But non-aggregates do not have this; they can only be initialized by their constructor. Both player and card have implicitly-generated default constructors taking no arguments, and that's all.


Your compiler appears to be treating card as an aggregate, but player not.

In C++11 this is correct, from 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).

However in C++14 (N3936) this was changed to:

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

The = 5 in your code is a brace-or-equal-initializer for a non-static data member, so we can see that in C++11 player is not an aggregate, but in C++14 player is an aggregate.

Testing with g++, I found that g++ 5.1 implements this behaviour correctly - the code is rejected with -std=c++11 and accepted with -std=c++14 . However, g++ 4.9.2 rejects the code with -std=c++14 , so this would be a compiler bug in that version of g++.


Conclusion: If you have access to g++ 5.1 (or another compiler which correctly implements C++14) then a solution would be to use the -std=c++14 flag when compiling your code. Otherwise you'll have to put in some ugly workarounds.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM