您可以将
type_index
使用比较器生成所需顺序的自定义类型。
示例来自
cppreference
修改使用
std::map
而不是
std::unordered_map
使用自定义比较器:
#include <iostream>
#include <typeinfo>
#include <typeindex>
#include <map>
#include <string>
#include <memory>
struct A {
virtual ~A() {}
};
struct B : A {};
struct C : A {};
struct my_type_index {
std::type_index index = std::type_index(typeid(void));
my_type_index() = default;
my_type_index(std::type_index i) : index(i) {}
bool operator<(const my_type_index& other) const {
static std::map< std::type_index,int> rank{
{ std::type_index(typeid(A)) , 1},
{ std::type_index(typeid(B)), 2},
{ std::type_index(typeid(double)), 3},
{ std::type_index(typeid(int)), 4},
{ std::type_index(typeid(C)), 5}
};
return rank[index] < rank[other.index];
}
};
int main()
{
std::map<my_type_index, std::string> type_names;
type_names[std::type_index(typeid(int))] = "int";
type_names[std::type_index(typeid(double))] = "double";
type_names[std::type_index(typeid(A))] = "A";
type_names[std::type_index(typeid(B))] = "B";
type_names[std::type_index(typeid(C))] = "C";
for (const auto& e : type_names) {
std::cout << e.first.index.name() << " " << e.second << "\n";
}
}
output
:
1A A
1B B
d double
i int
1C C
Fran§ois Andrieux建议进行改进:
struct my_type_index {
std::type_index index = std::type_index(typeid(void));
int rank = 0;
my_type_index() = default;
my_type_index(std::type_index i) : index(i) {
auto it = ranks.find(i);
if (it != ranks.end()) rank = it->second;
}
static const std::map<std::type_index,int> ranks;
bool operator<(const my_type_index& other) const {
return rank < other.rank;
}
};
const std::map<std::type_index,int> my_type_index::ranks = [](){
std::map<std::type_index,int> result;
std::type_index index_order[] = {
std::type_index(typeid(A)),
std::type_index(typeid(B)),
std::type_index(typeid(double)),
std::type_index(typeid(int)),
std::type_index(typeid(C))
};
for (size_t i = 0; i < std::size(index_order);++i){ result[ index_order[i]] = i+1; }
return result;
}();
排名存储在静态地图中
ranks
和每个实例
rank
已经在施工中进行了评估(而不是每次比较,即比较现在更便宜)。此外,映射现在是从一个更健壮的数组生成的(您不能再错误地键入索引/排名)。此外,地图是
const
,即
find
而不是
operator[]
用于查找。不在地图中的元素将被分配等级0。事实上,之前也是这样,但之前
操作员[]
可能会向地图中添加不必要的元素。