我正在编写一小段代码,以弄清楚如何将不同的模板专长存储到一个数据结构中(例如vector
)。我知道tuple
,但这不好,因为我希望能够在构建tuple
之后追加专业化知识。
下面是我想到的一小段代码。简而言之,我的想法是让每个模板特化都从共同的class Element
继承,然后将此类实例存储到vector<Element>
中。那行得通,但是现在当我从vector
访问该数据时,我以Element
的身份访问它。我需要某种方法来找出哪个Element
与哪个模板专门化配对。
在typeid
中的元素上直接使用vector
会返回基本类型。我试图通过让成员函数runtime_type
从子类返回该信息来解决此问题。不幸的是,由于SparseSet<T>
中的成员函数没有覆盖基类中的虚拟成员函数,因此无法正常工作。我不确定为什么。
#include <vector>
#include <iostream>
#include <tuple>
#include <typeinfo>
#include <algorithm>
class Element
{
public:
virtual const std::type_info& runtime_type()
{
std::cout << " Called base ";
return typeid(*this);
}
virtual ~Element() = default;
};
template<class T>
class SparseSet : public Element
{
public:
T param;
const std::type_info& runtime_type() override
{
std::cout << " Called derived ";
return typeid(*this);
}
};
class Manager
{
public:
std::vector<Element> elements;
template<class T>
bool has()
{
const auto it = std::find_if(elements.begin(), elements.end(), [](auto &element) {
std::cout << "typeid(element) = " << element.runtime_type().name() << std::endl;
std::cout << "typeid(T) = " << typeid(T).name() << std::endl;
return typeid(element) == typeid(T);
});
return it != elements.end();
}
};
int main()
{
SparseSet<int> ss_int;
ss_int.param = 3;
SparseSet<char> ss_char;
ss_char.param = 'a';
Manager manager;
manager.elements.push_back(ss_int);
manager.elements.push_back(ss_char);
std::cout << manager.has<SparseSet<int>>() << std::endl;
return 0;
}
运行上面的代码段时,使用在线编译器coliru(g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
),得到以下输出。
typeid(element) = Called base 7Element
typeid(T) = 9SparseSetIiE
typeid(element) = Called base 7Element
typeid(T) = 9SparseSetIiE
0
答案 0 :(得分:1)
std::vector<Element> elements;
这意味着elements
是vector
类句点实例的Element
。例如,vector
分配内存时,它为每个实例分配连续的空间,而sizeof(Element)
则保留。
SparseSet
的实例?
您可能要使用std::vector<std::unique_ptr<Element>>
,因为unique_ptr<Element>
可以容纳指向SparseSet
的指针。