C++ 模板C++;:如何访问std::map和std::set的迭代器值?
我有一个特定的搜索功能。因为它在C++ 模板C++;:如何访问std::map和std::set的迭代器值?,c++,templates,dictionary,stl,set,C++,Templates,Dictionary,Stl,Set,我有一个特定的搜索功能。因为它在std::set和std::map上都使用过,所以它在我们的代码中是重复的(不使用模板) 我必须维护这两个函数,我想使用一个模板将它们移动到一个函数中(然后只需要维护一个搜索前置) 我找不到如何将迭代器转换为容器的值\u类型。对于std::set,您只需要取消对迭代器(*iter)的引用,但是对于std::map,您需要访问迭代器的第二项(这是一对)iter->second 以下是一个单独的例子: template <class Container, cla
std::set
和std::map
上都使用过,所以它在我们的代码中是重复的(不使用模板)
我必须维护这两个函数,我想使用一个模板将它们移动到一个函数中(然后只需要维护一个搜索前置)
我找不到如何将迭代器转换为容器的值\u类型
。对于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 );
}
模板bool MyFindFunction(常量容器和容器、对象和已找到)
{
Container::const_iterator iter=Container.begin();
//在这里执行我的特殊搜索程序
//请注意,此代码还需要访问迭代器的值。。。
if(iter!=container.end())
{
found=*iter;//这适用于set,但不适用于map
found=iter->second;//这适用于map,但不适用于set
//如何使它同时适用于两种情况??
返回true;
}
其他的
{
返回false;
}
}
int main()
{
std::设置mySet;
std::map myMap;
双发现=0;
MyFindFunction(mySet,found);
MyFindFunction(myMap,已找到);
}
请注意,特殊搜索过程还需要访问值\u类型
(或地图的映射\u类型
),因此,将此过程移动到模板函数,并在调用搜索过程函数后使用MyFindFunctionInMap
和MyFindFunctionInSet
函数处理迭代器到值的转换将不会有帮助
PS:对不起,我使用的是C++98..您可以使用从映射
-like迭代器构建一个集
-like迭代器
创建一个内部模板函数,该函数由类似于的迭代器集参数化,并且只将迭代器(而不是容器)作为参数。将原始迭代器或转换后的迭代器分派到此函数
编辑如果您无法使用boost,请创建一些functor来访问您的资料:
#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;
}
#包括
#包括
#包括
使用名称空间std;
模板
结构访问密钥
{
模板
常量键和运算符()(常量参考和v)常量
{
首先返回v;
}
};
模板
结构访问密钥
{
模板
常量键和运算符()(常量参考和v)常量
{
返回v;
}
};
模板
空fn(集装箱t)
{
访问键a;
cout您可以使用模板函数重载
来区分这些情况:
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; }
一个实用的解决方案是使用额外的布尔参数来确定容器是否为映射:
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
}
..
}
模板bool MyFindFunction(const容器和容器、Object和found、bool isMap){
..
如果(!isMap){
found=*iter;//这适用于set,但不适用于map
}
否则{
found=iter->second;//这适用于map,但不适用于set
}
..
}
只需使用模板迭代器创建一个access
函数,并为map/set迭代器实现它。因此,您没有完整的函数实现,只是有问题的访问点:std::map
的value\u type
是std::pair
,这正是取消对迭代器的引用给你。你要找的类型是mapped_type
。是的,我要找的是mapped_type,它不是为集合定义的…这一个只有值_type…@jpo38请参阅更新。以后,你可能想在你的问题中声明限制,顺便说一句。对此很抱歉。access_key操作符返回v.first,应该是v.second吗?你能支持吗请看一个关于如何使用此access\u key结构的示例?这提供了对键的访问,而不是对值的访问,对吗?我适应了值(将v.first
更改为v.second
并将值从key
返回到value
,但它不起作用)@jpos38只需将第一个
更改为第二个
。其余的保持不变。让我们来看看。我喜欢这样,但它不编译(我使用的是VS2010)。显然编译器没有使用map version函数。有没有办法传递get_value函数作为参数使用?@jpo38我的错。我已经更新了答案,请再次检查。它工作得很好,是解决问题的一种非常简单的方法。谢谢!这不起作用。即使只在isMap设置为true时使用,编译器也会投诉错误C2440:“=”:无法从“const std::pair”转换为“double”
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
}
..
}