C++ - 基本容器问题

发布于 2024-09-12 10:51:11 字数 526 浏览 6 评论 0原文

应该如何处理以下情况:

我有一些几何存储,它是来自顶点类型的模板

template <typename T> struct Geometry {

std::vector<T>& GetVertices() { ... }

const void* RawVertices() const { ... }

}

这工作正常,除非我想存储不同类型的几何图形(例如,Geometryg1Geometryg2 在一个容器中

这可能吗?

或者我应该如何实现几何存储 。 (我可以使用一个容器存储和检索不同类型的几何图形)或者以某种方式将 T 类型映射到 Geometry 类型?

有什么建议吗

How should the following cases be handled:

I have some geometrical storage, which is a template from vertex type.

template <typename T> struct Geometry {

std::vector<T>& GetVertices() { ... }

const void* RawVertices() const { ... }

}

This works fine, unless I want to store different types of geometries (for instance, Geometry<Vertex1> g1 and Geometry<Vertex2> g2 in one container.

Is this possible?

Or how should I implement geometry storage (where I can store and retrieve different types of geometries using one container) or maybe somehow map T type to Geometry<T> type?

Any advices?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦断已成空 2024-09-19 10:51:12

由于容器与其可以包含的一种数据类型相关联,因此您可以创建一个类 GeometryBase,从中派生出所有 Geometry,然后存储 GeometryBase容器中的 指针

struct GeometryBase
{
    // Non-template methods might go here.
    // Don't forget to declare the base class destructor virtual.
};

template <typename T> struct Geometry : public GeometryBase
{
    // Template methods go here
};

编辑:
在某些时候,您必须决定要获取哪种类型的顶点容器(我的方法)您想要对顶点执行什么操作(Vijay Mathew 的方法),然后您必须进行dynamic_cast< ;>为了访问派生类的方法。

另一个建议:
如果类型与您在评论中描述的不同,实际上将它们视为不同的类型可能会更好。
例如,您可以为每个 Geometry 模板实例创建一个单独的容器。

class SomeStorageClass
{
/* ... */
private:
    std::vector< Geometry<Vertex1> > m_vertex1Geometries;
    std::vector< Geometry<Vertex2> > m_vertex2Geometries;
};

如果您有对一种几何体(使用 Vertex1::GetPos(),使用您的示例)或另一种几何体(Vertex2::GetUV())进行操作的函数那么这些函数的实现方式可能完全不同,因此应该是需要不同类型参数的单独函数。

Since a container is tied to one type of data it can contain, you could create a class GeometryBase from which all Geometry<T> are derived and then store GeometryBase pointers in your container.

struct GeometryBase
{
    // Non-template methods might go here.
    // Don't forget to declare the base class destructor virtual.
};

template <typename T> struct Geometry : public GeometryBase
{
    // Template methods go here
};

Edit:
At some point you will have to decide which type of vertex container you want to get (my approach) or what you want to do with a vertex (Vijay Mathew's approach) and then you'll have to dynamic_cast<> in order to get access to the derived class methods.

Another suggestion:
If the types are as different as your describe in your comments, it might actually be better to treat them as different types.
For example, you could create a separate container for each Geometry<> template instance.

class SomeStorageClass
{
/* ... */
private:
    std::vector< Geometry<Vertex1> > m_vertex1Geometries;
    std::vector< Geometry<Vertex2> > m_vertex2Geometries;
};

If you have functions that operate on one kind of geometry (using Vertex1::GetPos(), to use your example) or the other (Vertex2::GetUV()) then these functions are probably implemented quite differently and thus deserve to be separate functions expecting diferent types of parameters.

乖乖哒 2024-09-19 10:51:12

异构容器(即存储不止一种类型的对象)引入了相当多的问题——举一个明显的例子,当您检索一个对象时,您必须做一些事情来确定您正在检索哪种类型的对象。

C++ 中内置的容器采用简单的路线:它们是同类的——它们只存储一种类型的对象。如果您想存储两种不同类型的对象,则需要将这两种类型包装为存储在容器中的第三种类型(通常与指示特定对象实际类型的内容一起)。例如,您可以这样做:

class vertex1 {};

class vertex2 {};

class vertex {
    vertex1 *v1;
    vertex2 *v2;
public:
    vertex(vertex1 *init1) : v1(init1), v2(NULL) {}
    vertex(vertex2 *init2) : v1(NULL), v2(init2) {}
};

std::vector<vertex> vertices;

当然,有很多变体(例如,存储指向基类的指针),但最终归结为一件事:集合本身保存一种类型的对象,并且该类型以某种方式管理您需要处理的其他两种类型。

Heterogeneous containers (i.e., that store more than one type of object) introduce quite a few problems -- for an obvious example, when you retrieve an object, you have to do something to figure out which kind of object you're retrieving.

The containers built into C++ take the simple route: they're homogeneous -- they only store one type of object. If you want to store objects of two different types, it's up to you to wrap both of those into some third type that you store in the container (usually along with something to indicate which type a particular object really is). For example, you could do something like this:

class vertex1 {};

class vertex2 {};

class vertex {
    vertex1 *v1;
    vertex2 *v2;
public:
    vertex(vertex1 *init1) : v1(init1), v2(NULL) {}
    vertex(vertex2 *init2) : v1(NULL), v2(init2) {}
};

std::vector<vertex> vertices;

Of course, there are lots of variations (e.g., storing a pointer to a base class), but in the end it comes down to one thing: the collection itself holding one type of object, and that type somehow or other managing the two other types you need to deal with.

清浅ˋ旧时光 2024-09-19 10:51:12
class IGeometry
{
public:
    virtual const void* RawVertices() const = 0;
    virtual ~IGeometry() {}

    template <typename T>
    std::vector<T>& GetVertices() const 
    { 
        typedef const Geometry<T>* AppropriateDerivedClass;
        return dynamic_cast<AppropriateDerivedClass>(this)->GetVertices();
    };
};
class IGeometry
{
public:
    virtual const void* RawVertices() const = 0;
    virtual ~IGeometry() {}

    template <typename T>
    std::vector<T>& GetVertices() const 
    { 
        typedef const Geometry<T>* AppropriateDerivedClass;
        return dynamic_cast<AppropriateDerivedClass>(this)->GetVertices();
    };
};
原谅过去的我 2024-09-19 10:51:11

由于 GetVertices 只会返回 Vertex 类型的对象,因此我建议您从泛型转向面向对象的设计。

class Vertex
{
   ....
};

class Vertex1 : public Vertex 
{
   ....
};

class Vertex2 : public Vertex 
{
   ....
};

typedef std::vector<Vertex*> Vertices;

struct Geometry
{
    const Vertices& GetVertices() const { .... }
    ....
};

As GetVertices will only return objects of type Vertex, I suggest you move to an Object Oriented design from generics.

class Vertex
{
   ....
};

class Vertex1 : public Vertex 
{
   ....
};

class Vertex2 : public Vertex 
{
   ....
};

typedef std::vector<Vertex*> Vertices;

struct Geometry
{
    const Vertices& GetVertices() const { .... }
    ....
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文