[英]How to create a vector for base class generic types to use concrete type elements
If sb.如果某人。 can change the title to something more understandable I'd be very thankful
可以将标题更改为更容易理解的内容,我将非常感谢
This is my current implementation:这是我目前的实现:
std::vector<Zone<sf::CircleShape>*> allZones;
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();
std::vector<Zone<sf::CircleShape>*> communityAreas = initializer->initCommunityAreas();
I'd love to have something like this:我很想有这样的东西:
std::vector<Zone<sf::Shape>*> allZones;
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();
std::vector<Zone<sf::RectangleShape>*> communityAreas = initializer->initCommunityAreas();
Where CircleShape
and RectangleShape
derive from the base class Shape
.其中
CircleShape
和RectangleShape
派生自基类Shape
。 I think that would be possible for a vector if this would be like the generic type for the vector
and not the generic type of the generic type of the vector.我认为这对于向量来说是可能的,如果这类似于
vector
的泛型类型而不是vector
的泛型类型的泛型类型。
One solution that comes in mind is that I make Zone
not a template class but like ZoneShape
and ZoneCircle : public ZoneShape
, ZoneRectangle : public ZoneShape
.想到的一个解决方案是,我使
Zone
不是模板类,而是像ZoneShape
和ZoneCircle : public ZoneShape
、 ZoneRectangle : public ZoneShape
。
That way I could to something like this:这样我就可以做这样的事情:
std::vector<ZoneShape*> allZones;
std::vector<ZoneCircle*> estates = initializer->initVillageEstates();
std::vector<ZoneRectangle*> communityAreas = initializer->initCommunityAreas();
I think that would work but I kinda found the template way more clean for my purpose.我认为这会起作用,但我觉得模板方式更适合我的目的。 So I have to figure out how this might work with that.
所以我必须弄清楚这如何与它一起工作。
To answer your overall question, there's no C++ way to automatically make templates follow the inheritance rules of their type parameters (some other languages like Scala will let you do this, but they're also generally not working with value types).为了回答您的整体问题,没有 C++ 方法可以自动使模板遵循其类型参数的继承规则(Scala 等其他一些语言可以让您这样做,但它们通常也不适用于值类型)。 As far as C++ is concerned, a vector of type A is a completely separate type from a vector of type B, even though they're both descended from the same template.
就 C++ 而言,类型 A 的向量与类型 B 的向量是完全不同的类型,即使它们都来自同一个模板。
It sounds like you realize that, though.不过,您似乎意识到了这一点。 As far as alternatives go, making separate
ZoneShape
classes for every single shape you might want to hypothetically add is tedious (and violates DRY), so let's not do that.就替代方案而言,为您可能想要添加的每个形状创建单独的
ZoneShape
类是乏味的(并且违反 DRY),所以我们不要这样做。 But if plain old templates don't support inheritance the way you want, and making more class inheritance is too repetitive, you could make use of a bit of both worlds:但是如果普通的旧模板不支持你想要的继承方式,并且创建更多的类继承太重复了,你可以利用两个世界:
class ZoneShape {
// Not sure what your Zone class needs to do,
// but include your functionality based on the
// base Shape class here.
public:
virtual void setShape(Shape* shape) = 0;
virtual Shape* getShape() = 0;
};
template<typename T>
class Zone : public ZoneShape {
protected:
// Implemented versions of the base type.
void setShape(Shape* shape) override;
Shape* getShape() override;
public:
// Specific to your specific type.
void setShape(T* t);
T* getSpecificShape(); // EDIT: This was originally "T* getShape()",
// which cannot be overloaded.
};
std::vector<ZoneShape*> allZones;
std::vector<Zone<sf::CircleShape>*> estates = initializer->initVillageEstates();
std::vector<Zone<sf::RectangleShape>*> communityAreas = initializer->initCommunityAreas();
It's not perfect (eg a Zone<SquareShape>*
cannot necessarily stack with a Zone<RectangleShape>*
), but it should allow you to have both generic containers for zones of all shape types as well as more specialized containers for specific shapes.它并不完美(例如
Zone<SquareShape>*
不一定与Zone<RectangleShape>*
堆叠),但它应该允许您拥有用于所有形状类型区域的通用容器以及用于特定形状的更专业的容器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.