我提出了以下代码,该代码演示了一种在STL集合上进行一般迭代并获得键值的技术,而无论该键如何存储。

这样做的上下文是我要重构两个函数,它们在两个集合上都具有相同的功能:一个是set<int>,另一个是map<int, int>,因此,在第一种情况下,我想对*it进行操作,而在第二种情况下,我要对it->first(其中it是const_iterator。)

重要的是,我想这样做,因为集合非常大,我不想仅从set创建map只是为了只处理一种特定类型。

#include <map>
#include <set>
#include <iostream>

using namespace std;

// General case for obtaining from, say, a set.
template< typename T >
const typename T::key_type getKey( const typename T::const_iterator& it )
{
    return *it;
}

// Specific case for a map<int,int>
template<>
const map<int, int>::key_type getKey< map<int, int> >( const map<int, int>::const_iterator& it )
{
    return it->first;
}

template< typename T >
void dumpOut( T& coll )
{
    for ( typename T::const_iterator it = coll.begin(); it != coll.end(); ++it )
    {
        const typename T::key_type& a = getKey<T>(it);
        cout << a << endl;
    }
}

int main()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(15);
    s1.insert(20);

    dumpOut< set<int> >( s1 );

    map<int, int> m1;
    m1.insert( pair<int, int>(11, -1) );
    m1.insert( pair<int, int>(16, -1) );
    m1.insert( pair<int, int>(21, -1) );

    dumpOut< map<int, int> >( m1 );

    return 0;
}

我的问题是:是否有可能使map<int,int>的特殊情况更为通用,因为该方法显然对于map总体上是有效的,而与键和值的实际含义无关。

任何指针(无双关语)将很有用。请注意,尽管我从学术 Angular 对使用C++ 11解决方案感兴趣,但我无法使用它。谢谢。

最佳答案

您在这里遇到一种C++语言问题-不允许对函数进行部分特化。
因此,它不能像这样简单:

// Specific case for a map<int,***>
template<typename Value_, typename Comp_, typename Alloc_>
const typename map<int, Value_, Comp_, Alloc_>::key_type getKey< map<int, Value_, Comp_, Alloc_> >( const typename map<int, Value_, Comp_, Alloc_>::const_iterator& it )
{
    return it->first;
}

幸运的是,允许类的部分特化-更改为这种方式:
// work - for let say - sets
template <class Type_>
struct Key {
   Key(typename Type_::const_iterator it) : value(*it) {}
   typename Type_::key_type value;
};

// work - for map<***>
template <class Key_, class Value_, class Comp_, class Alloc_>
struct Key<map<Key_, Value_,Comp_,Alloc_> > {
   typedef map<Key_, Value_,Comp_,Alloc_> Type_;
   Key(typename Type_::const_iterator it) : value(it->first) {}
   typename Type_::key_type value;
};


template< typename T >
const typename T::key_type getKey( const typename T::const_iterator& it )
{
    return Key<T>(it).value;
}

我在这里复制了更改的示例:http://ideone.com/tE2aC

关于c++ - 从C++ STL集合中获取通用key_type,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11261052/

10-11 23:04
查看更多