[英]Template C++: How to access iterator value for both std::map and std::set?
我有特定的搜索功能。 因為在std::set
和std::map
上都使用了它,所以它在我們的代碼中是重復的(不使用模板)。
我必須維護這兩個函數,並且我想使用模板將它們移至單個函數(然后僅維護一個搜索先例)。
我找不到如何將迭代器轉換為容器的value_type
。 對於std::set
,您只需要取消引用迭代器(* iter),但是對於std::map
,則需要訪問迭代器的第二項(一對) iter->second
。
這是一個孤立的示例:
template <class Container, class Object> bool MyFindFunction( const Container& container, Object& found )
{
Container::const_iterator iter = container.begin();
// do my special search procedure here
// note that this code also needs to access the iterator's value...
if ( iter != container.end() )
{
found = *iter; // this works for set, but not for map
found = iter->second; // this works for map, but not for set
// HOW TO MAKE IT WORK FOR BOTH??
return true;
}
else
{
return false;
}
}
int main ()
{
std::set<double> mySet;
std::map<int,double> myMap;
double found = 0;
MyFindFunction( mySet, found );
MyFindFunction( myMap, found );
}
請注意,特殊的搜索過程還需要訪問value_type
(或映射的mapped_type
),因此,將該過程移至模板函數並在調用搜索過程函數后讓MyFindFunctionInMap
和MyFindFunctionInSet
函數處理將迭代器轉換為值的操作不會有幫助。
PS:對不起,我使用的是C ++ 98。
您可以使用template function overload
來區分以下情況:
template <typename V>
inline V get_value(const V& v) { return v; }
template <typename K, typename V>
inline V get_value(const std::pair<K, V>& p) { return p.second; }
接着
found = get_value(*iter);
您可以使用boost::transform_iterator
從類似map
的迭代器構建類似set
的迭代器。
創建一個由類似set
的迭代器參數化的內部模板函數,並且僅將迭代器而不是容器作為參數。 派發原始迭代器或轉換后的迭代器到此函數。
編輯如果無法使用boost,請構建一些函子來訪問您的東西:
#include <map>
#include <set>
#include <iostream>
using namespace std;
template<class Key, class Value>
struct access_key
{
template<class Ref>
const Key &operator()(const Ref &v) const
{
return v.first;
}
};
template<class Key>
struct access_key<Key, Key>
{
template<class Ref>
const Key &operator()(const Ref &v) const
{
return v;
}
};
template<class Container>
void fn(Container t)
{
access_key<typename Container::key_type, typename Container::value_type> a;
cout << a(*t.begin()) << endl;
}
int main()
{
set<int> s;
s.insert(1);
map<int, int> m;
m[1] = 1;
fn(s);
fn(m);
return 0;
}
此訪問器依賴於鍵類型和值類型對於映射/集是不同的/相同的。
一種實用的解決方案是使用額外的布爾參數來確定容器是否為地圖:
template <class Container, class Object> bool MyFindFunction( const Container& container, Object& found, bool isMap ){
..
if(!isMap){
found = *iter; // this works for set, but not for map
}
else{
found = iter->second; // this works for map, but not for set
}
..
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.