簡體   English   中英

模板C ++:如何訪問std :: map和std :: set的迭代器值?

[英]Template C++: How to access iterator value for both std::map and std::set?

我有特定的搜索功能。 因為在std::setstd::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 ),因此,將該過程移至模板函數並在調用搜索過程函數后讓MyFindFunctionInMapMyFindFunctionInSet函數處理將迭代器轉換為值的操作不會有幫助。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM