我提出了以下代码,该代码演示了一种在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/