我正在编写一小段代码来弄清楚如何将不同的模板特化存储到一个数据结构中(例如vector
)。我知道,tuple
但这并不好,因为我希望能够在tuple
构建之后附加专业化。
下面是我想出的一段代码。简而言之,我的想法是让每个模板特化都继承自一个 common 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