【问题标题】:How to create a vector that saves elements of all types of the same template class如何创建一个向量来保存同一模板类的所有类型的元素
【发布时间】:2016-11-24 07:32:33
【问题描述】:

我有一个模板类:

template<typename A, typename B, typename C>
class blah{...};

我想创建一个 std::vector 来保存任何可能的 blah 对象。

例如

blah<float, int, string>

blah<string, string, char>

这些 blah 对象虽然来自同一个模板类,但本质上是不同的类型。如何声明一个 std::vector 来保存它们?

我想过使用std::variant,但我不能,因为要使用它,我需要枚举所有可能的模板参数组合:

std::variant<all possible template parameter combinations>

我考虑过使用 std::any,但我不能,因为我不知道如何从 std::any 类型转换回正确的类型?

我考虑过使用基类:

template<typename A, typename B, typename C>
class blah : public blah_base
{...};

并像这样声明一个向量:

std::vector<blah_base*>

但是,我仍然不知道如何从 blah_base* 类型转换回正确的类型?

【问题讨论】:

  • 您如何使用blah&lt;...&gt; 实例?你的用例是什么?不能用继承和虚函数解决吗?您尝试解决的实际问题是什么?
  • 你能提供bla的定义还是太长了?
  • 我正在尝试实现深度学习神经元网络。 blah 类型是张量。张量可以有不同的维度、设备类型和数据类型。所以真正的 blah 被定义为“template class {...};”
  • 老实说,我认为我的用例并不重要。我只想用一个虚拟类来简化我的问题。但如果你真的想知道代码,你可以在这里查看:github.com/dmlc/mshadow/tree/master/guide#tensor-data-structure

标签: c++ templates types metaprogramming template-meta-programming


【解决方案1】:

基本上,您需要的是多态性。您正在探索的所有选项都是多态性,这是解决此问题的最佳方法。但是,您说这个和其他变体:

我不知道如何从 blah_base* 类型转换回正确的类型

如果您发现自己需要这样做,那么您做错了什么。要么拥有 std::vector&lt;blah&lt;...&gt;&gt; 没有意义,要么你的 blahs 都需要满足 blah_base 合同。

你可以用虚函数解决这个问题:

class blah_base {
public:
    virtual void foo() = 0;
};

然后,您不必知道您拥有哪种类型的blah,只需调用相应的foo 函数即可。

【讨论】:

【解决方案2】:

好吧,在不太了解您的用例的情况下,我假设您将拥有三个向量;每个模板类型一个。你可以这样实现blah

#include <vector>

template<typename A, typename B, typename C>
class blah
{
public:
    // Put stuff here.
    void AddToVectorA(A item);
    void AddToVectorB(B item);
    void AddToVectorC(C item);
private:
    std::vector<A> _a;
    std::vector<B> _b;
    std::vector<C> _c;
};

template<typename A, typename B, typename C>
void blah<A,B,C>::AddToVectorA(A item)
{
    _a.push_back(item);
}

template<typename A, typename B, typename C>
void blah<A,B,C>::AddToVectorB(B item)
{
    _b.push_back(item);
}

template<typename A, typename B, typename C>
void blah<A,B,C>::AddToVectorC(C item)
{
    _c.push_back(item);
}

int main()
{
    blah<int, double, float> b;
    b.AddToVectorA(2);

    return 0;
}

您也可以公开这三个向量,但人们可以使用它们;您也可以查看tuple。仅供参考:我现在测试了代码,它可以工作。

【讨论】:

  • 我的麻烦是类型的组合很大,我需要有很多向量,而不仅仅是 3 个。
猜你喜欢
  • 1970-01-01
  • 2017-08-23
  • 2016-02-15
  • 2017-08-24
  • 2011-05-15
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多