我有以下地圖:
std::map<std::type_index, std::set<Status *>> statuses;
它存盤了那里不同子類的集合Status,這要歸功于它們的std::type_index. 但是,我想控制此映射中物件的順序(例如,我有兩個類Burn,Stun它們繼承自Status,并且我希望typeid(Stun) < typeif(Burn)當我遍歷映射時,我得到std::set<Stun>之前的std::set<Burn>)。
我考慮過實作一個自定義type_index類,但如果沒有 boost,我似乎找不到任何方法來做到這一點,這是一個巨大的庫,我不想將它包含到我的專案中。
有關如何在地圖中自定義訂單的任何建議?
uj5u.com熱心網友回復:
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";
int i;
double d;
A a;
// note that we're storing pointer to type A
std::unique_ptr<A> b(new B);
std::unique_ptr<A> c(new C);
for (const auto& e : type_names) {
std::cout << e.first.index.name() << " " << e.second << "\n";
}
}
輸出:
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。實際上之前也是如此,但之前operator[]可能會向地圖中添加不必要的元素。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/465137.html
上一篇:按值對日期字典串列進行排序
