简体   繁体   中英

Why class member data has to be static in order to be accessed by templated struct member of templated class?

The question title could probably be better written... but anyways:

#include <array>
#include <iostream>
#include <numeric> //std::iota
#include <sstream>

template<std::size_t N>
class JolloManager
{
private:
    enum PlayerId { princeID = 100, princessID = 101 };
    PlayerCards<princeID,   2> prince;
    PlayerCards<princessID, 3> princess;
    std::array<int, N> deck;
private:
    template<int ID, int c> struct PlayerCards
    {
        int id {ID};
        int cards[c] {0};
        friend std::istream& operator >> (std::istream& is, PlayerCards& p) {
            for(auto& i : p.cards) {
                is >> i;
                //set deck[index] = prince or princess FLAG
                deck[i] = p.id; //error: invalid use of non-static data member 'JolloManager<N>::deck'
            }
            return is;
        }
    };
public:
    JolloManager() {
        std::iota(deck.begin()+1, deck.end(), 1);
    };
public:
    bool Read();
    int FinalCard();
};

template<std::size_t N>
bool JolloManager<N>::Read()
{
    static std::string line;
    std::getline(std::cin, line);
    std::istringstream issline(line);

    issline >> prince;
    issline >> princess;

    if(prince.cards[0] == 0) {
        return false;
    }

    return true;
}

int main()
{
    JolloManager<52> JManager;
    JManager.Read();
    return 0;
}

Why must deck be static? This would defeat the use of multiple instances of the class.

First of all functions declared with friend in class definitions are not member functions of these classes. They are instead placed into the enclosing namespace.

Secondly, enclosing classes do not intrinsically contain any instance of a nested class as member, nor does an instance of the nested class have any intrinsic reference to an instance of the enclosing class.

Therefore there is no instance of JolloManager that deck could refer to if it is a non-static member.

You need to decide which instance's deck you mean and you need to provide that information to the operator overload, by eg holding a pointer/reference to the JolloManager instance in the PlayerCards instance passed to it, so that you can eg use p.jollo_manager.deck or p.jollo_manager->deck .

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