我有一个类型为
class Piece
{
public:
pieceType ID;
//...
}
class Infantry :
public Piece
{
public:
//...
};
class Artillery :
public Piece
{
public:
//...
};
//...
//In some other classes somewhere
std::map<pieceType, std::vector<Piece*>*> units;
units.emplace(Infantry_, new std::vector<Infantry*>);
units.emplace(Artillery_, new std::vector<Artillery*>);
//...
template<typename T>
std::vector<T*> operator+(std::vector<T*> a, Piece * b) {
a.push_back(static_cast<T*>(b));
return a;
}
add(Piece * piece){
units.at(piece->ID) = units.at(piece->ID) + piece;
}
我也知道这段代码有一些错误,更多的是我想说的例子。
答案 0 :(得分:0)
您必须使用虚拟功能来获取每个子类的ID
class Piece
{
public:
virtual PieceType ID() const = 0;
}
class Artillery
{
public:
virtual PieceType ID() const override { /* return your ID for Artillery */ }
}
class Infantery
{
public:
virtual PieceType ID() const override { /* return your ID for Infantery */ }
}
答案 1 :(得分:0)
std::vector<Piece*>
与std::vector<Infantry*>
或std::vector<Artillery*>
之间没有任何关系,因此您的地图只能包含std::vector<Piece*>
个。
这是有充分理由的。假设您有一个std::vector<Infantry*>
,并将指向它的指针放到std::map<pieceType, std::vector<Piece*>*>
中。然后,您可以在地图中插入Artillery *
。
除了直接公开std::vector<Piece*>
之外,您还可以公开其(转换为特定子类型)的(只读)视图。
使用范围库
auto asInfantry = ranges::view::transform([](Piece * p){ return static_cast<Infantry *>(p); });
auto asArtillery = ranges::view::transform([](Piece * p){ return static_cast<Artillery *>(p); });
class PieceMap
{
std::map<pieceType, std::vector<Piece*>> units;
public:
auto Infantry() { return units.at(Infantry_) | asInfantry; }
auto Artillery() { return units.at(Artillery_) | asArtillery; }
};