在我的代碼中,我有很多地方需要獲取 std::vector 的東西并將其放入由某些東西索引的 std::map 中。例如這里有兩個代碼片段:
//sample A
std::map<Mode::Type, std::vector<Mode>> modesByType;
for( const auto& mode : _modes ) {
Mode::Type type = mode.getType();
auto it = modesByType.find( type );
if( it == modesByType.end() ) {
std::vector<Mode> v = { mode };
modesByType.insert( std::pair( type, v ) );
} else {
it->second.push_back( mode );
}
}
//sample B
std::map<unsigned, std::vector<Category>> categoriesByTab;
for( const auto& category : _categories ) {
unsigned tabIndex = category.getTab();
auto it = categoriesByTab.find( tabIndex );
if( it == categoriesByTab.end() ) {
std::vector<Category> v = { category };
categoriesByTab.insert( std::pair( tabIndex, v ) );
} else {
it->second.push_back( category );
}
}
我想概括一下并創建一個模板函式,如:
template<typename T, typename V>
std::map<T,std::vector<V>> getMapByType( const std::vector<V>& items, ?? ) {
std::map<T,std::vector<V>> itemsByType;
for( const auto& item : items ) {
unsigned index = ??;
auto it = itemsByType.find( index );
if( it == itemsByType.end() ) {
std::vector<V> v = { item };
itemsByType.insert( std::pair( index, v ) );
} else {
it->second.push_back( item );
}
}
return itemsByType;
}
我的問題是,我如何定義 ?? 這個函式的引數,以便我可以呼叫正確的 V.foo() 函式來獲取地圖的索引值?
注意,我不想讓這個模板(V)接受的所有類都繼承自基類。我可以以某種方式指定一個 lambda 引數嗎?
uj5u.com熱心網友回復:
have a pointer to a member fn as an extra parameter
template<typename T, typename V>
std::map<T,std::vector<V>> getMapByType( const std::vector<V>& items, T (V::*fn)()const) {
std::map<T,std::vector<V>> itemsByType;
for( const auto& item : items ) {
T index = (item.*fn)();
auto it = itemsByType.find( index );
if( it == itemsByType.end() ) {
std::vector<V> v = { item };
itemsByType.emplace( index, v );
} else {
it->second.push_back( item );
}
}
return itemsByType;
}
auto res = getMapByType(items, &Category::getTab);
uj5u.com熱心網友回復:
您可以傳遞一個確定密鑰的函式,如下所示:
template <typename V,typename F>
auto getMapByType( const std::vector<V>& items,F func) {
using key_t = std::decay_t<delctype(func(item[0]))>;
std::map<key_t,std::vector<V>> result;
for (const auto& item : items) {
result[ func(item) ].push_back(item);
}
return item;
}
然后你可以這樣稱呼它
std:vector<Category> vec;
auto m = getMapByType( vec, [](const Category& c) { return c.getTab(); });
或者
std:vector<Mode> vec;
auto m = getMapByType( vec, [](const Category& c) { return c.getType(); });
請注意,operator[]這已經完成了您重新實作的操作。它試圖找到具有給定鍵的元素。如果不存在,則插入一個默認構造的,然后回傳對映射值的參考。
即使沒有operator[]你也不需要findthen insert,因為insert只有在沒有給定鍵的元素存在時才會插入。insert回傳元素的迭代器和bool告訴您插入是否實際發生的 a。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/532068.html
標籤:C 字典模板拉姆达
上一篇:防止模板化類將自身用作實體
