【问题标题】:Storing templated objects in a vector (Storing Class<int>, Class<double> in a single vector)将模板化对象存储在向量中(将 Class<int>、Class<double> 存储在单个向量中)
【发布时间】:2019-06-24 13:51:05
【问题描述】:

有一个模板类,就这样吧

template<typename T> class A { std::vector<T> data; };

我在这里面临的问题是,用户可以创建该类的多种类型,但我需要跟踪它们,最好的情况是我在另一个向量中引用了这些对象,但这不起作用,因为所有类型都是不同的。 你能推荐一个可以封装这个的好的设计模式吗?

我可以存储指针然后对其进行类型转换,但它并不优雅。

如果提供的解决方案足够好,我也可以更改架构。 我要解决的基本问题是,我有一类自定义类型的向量,如何存储它们。

【问题讨论】:

  • 为什么需要将它们存储在一个容器中?你能举例说明如何使用这个引用向量吗?
  • T所代表的类型是否有某种关联?即通用接口还是通用基类?

标签: c++ oop design-patterns stdvector


【解决方案1】:

std::any 是现代 c++17 解决方案。具体来说,您应该使用

A<int> a;
a.data.push_back(0);

// fill refernces...
std::vector<std::any> refernces; 
refernces.push_back(&a.data[0]);

// check which type is active.
if(int** iPtr = std::any_cast<int*>(&references[0]); iPtr != nullptr)
{
     // its an int*
     int& i = **iPtr;
     // do something with i.
}

这些指针可以指向A&lt;int&gt;::dataA&lt;double&gt;::data 向量。

如需完整参考,请参阅此处https://en.cppreference.com/w/cpp/utility/any

【讨论】:

  • 我使用的是现代 c++,但这只是一个例子。可以有无数个示例,例如自定义类等。示例:A var;
  • 您可以使用std::any。但是你真的应该认真考虑这是否是一个整体的好设计。你真的需要在那里允许任何类型吗?此外,如果A&lt;T&gt;::data 重新分配/调整大小,所有这些指针都将失效。您可能需要更好的整体结构。
  • std::any,然后在提取时进行强制转换,似乎有点不安全。但是,是的,约束是存在的,有太多不同的对象需要跟踪。顺便说一句,我已经更新了这个问题,你可以为这个问题推荐一个好的设计,我可以重构我的代码。
【解决方案2】:

正如之前的 cmets 所说 - 您首先需要确保这是您所需要的。

话虽如此,我的一个项目中也有类似的需求,我最终通过继承和 PIMPL 解决了,如下:

class A{
private:
    struct Abstract {
        virtual void f() = 0;
    };

    template <typename T>
    struct Implementation : public Abstract {
        std::vector<T> data;
        virtual void f() {...}
    };

    std::unique_ptr<Abstract> impl;

public:
    template <typename T>
    A(): impl(std::make_unique<Implementation<T> >()){}

    void f() {impl->f();}
};

这允许您创建A 类型对象的容器,并通过其中定义的公共接口(方法f)访问它们。每个A 对象的基础类型T 在构造时指定。特定于 T 类型的所有其他实现细节都被隐藏了。

该解决方案存在虚函数的固有开销。我不确定它与 std::any 方法的性能相比如何。

【讨论】:

  • std::any 内部使用虚函数/继承。性能将大致相同。我之前展示的解决方案是针对不使用继承的std::variant
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
相关资源
最近更新 更多