求向量的一个元素,它是在映射中呈现的
Find an element of vector which is presented in the map
我需要找到在地图中呈现的向量元素。困难之处在于vector是由结构体组成的,因此您应该首先调用成员函数从结构体中提取值,以便将其与map元素进行比较。
for循环很简单:
vector<A>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
if( mp.count( it->getKey() ) )
{
break;
}
}
我的问题是:有没有办法在一行中完成,比如
//this doesn't work as count accepts key_type
vector<A>::iterator it = find_if( vec.begin(), vec.end(), boost::bind( &map<string, string>::count, mp, boost::bind( &A::getKey, _1 ) )) != 0);
完整示例,用于测试
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/assign.hpp>
using namespace std;
class A{
public:
A( const std::string& key )
: key( key ) {}
std::string getKey(){ return key; }
private:
std::string key;
};
int main(int argc, const char *argv[]) {
map<string, string> mp = boost::assign::map_list_of( "Key1", "Val1" ) ( "Key2", "Val2" ) ( "Key3", "Val3" );
vector<A> vec = boost::assign::list_of( "AAA" ) ( "Key2" ) ( "BBB" );
// vector<A>::iterator it = find_if( vec.begin(), vec.end(), boost::bind( &map<string, string>::count, mp, boost::bind( &A::getKey, _1 ) )) != 0);
vector<A>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
if( mp.count( it->getKey() ) )
{
break;
}
}
cout << ( it != vec.end() ? "found" : "not found" ) << endl;
return 0;
}
Thanks in advance
您的解决方案很接近,只是有一个右括号太多了。将每个圆括号放在换行符上,每一层都有缩进,强调无效圆括号:
vector<A>::iterator it = find_if
(
vec.begin(), vec.end(), boost::bind
(
&map<string, string>::count, &mp, boost::bind
(
&A::getKey, _1
)
)
) // one too many
!= 0);
在其最简单的形式中,这一行变成了iterator = find_if(...) != 0)
,这将导致编译器失败:
- 无法找到
operator!=(iterator, int)
。 -
!= 0)
中的)
令牌。
加上正确的括号,!= 0
使用boost::bind
提供的操作符重载。这一行看起来像:
vector<A>::iterator it = find_if(vec.begin(), vec.end(),
boost::bind(&map<string, string>::count, &mp,
boost::bind(&A::getKey, _1)) != 0);
但是,要考虑这样一个简单操作的可读性。如果简单的
for
循环不够通用和可重用,那么考虑将其隐藏在一个方便的函数中:
template <typename InputIterator,
typename C,
typename Fn>
InputIterator find_if_contains(
InputIterator first,
InputIterator last,
const C& container,
Fn fn)
{
while (first != last)
{
if (0 != container.count(fn(*first))) return first;
++first;
}
return last;
}
...
vector<A>::iterator it = find_if_contains(
vec.begin(), vec.end(),
mp, boost::bind(&A::getKey, _1)
);
否则,自定义谓词类型可以增强可读性,同时为不同类型的重用提供一些额外的灵活性。例如,考虑以下谓词类型,它适用于各种类型的关联容器:
template <typename C,
typename Fn>
struct contains_predicate
{
contains_predicate(const C& container, Fn fn)
: container_(&container), fn_(fn)
{}
template <typename T>
bool operator()(T& t)
{
return 0 != container_->count(fn_(t));
}
const C* container_;
Fn fn_;
};
template <typename C,
typename Fn>
contains_predicate<C, Fn>
contains(const C& container, Fn fn)
{
return contains_predicate<C, Fn>(container, fn);
}
...
vector<A>::iterator it = find_if(vec.begin(), vec.end(),
contains(mp, boost::bind(&A::getKey, _1)));
在c++ 11中,使用lambda:
find_if(vec.begin(), vec.end(), [&](A const & a){return mp.count(a.getKey());});
但是因为你在使用Boost。赋值而不是统一初始化,也许你不能那样做。恐怕我不知道如何单独使用bind
构造这样的函子
相关文章:
- 如何从存储在std::映射中的std::集中删除元素
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 删除映射和分割错误中的一个过去结束元素
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 访问映射向量的映射元素(c++)
- 为什么 unordered_map::equal_range upper_bound 如果键小于第一个映射元素,则返回
- 根据类成员对同一密钥的多映射元素进行排序
- C++查找并擦除多映射元素
- C++ for_each循环找不到指向映射元素
- 创建映射元素时,请避免使用值副本
- 从常量迭代器到映射向量,获取映射向量中映射元素的键和值
- c++中如何更改映射元素的值
- 传递对映射元素的引用作为参数
- 如果没有找到映射元素将返回什么
- 不能访问指针-向量映射元素
- 存储内部排序映射元素的最快方式
- 无序多映射元素插入
- 哈希映射元素的值未正确打印
- 修改所有映射元素的键
- 复制映射元素的正确方法