Boost 查找地图中显示的向量元素

Boost 查找地图中显示的向量元素,boost,bind,std,c++,Boost,Bind,Std,C++,我需要找到一个向量的元素,它在地图上显示。最困难的部分是向量由结构组成,所以您应该首先调用成员函数从结构中提取值,将其与映射元素进行比较 因此,使用for cycle非常简单: vector<A>::iterator it; for( it = vec.begin(); it != vec.end(); ++it ) { if( mp.count( it->getKey() ) ) { break; } } vector::迭代器; f

我需要找到一个向量的元素,它在地图上显示。最困难的部分是向量由结构组成,所以您应该首先调用成员函数从结构中提取值,将其与映射元素进行比较

因此,使用for cycle非常简单:

vector<A>::iterator it;
for( it = vec.begin(); it != vec.end(); ++it )
{
    if( mp.count( it->getKey() ) )
    {
        break;
    }
}
vector::迭代器;
for(it=vec.begin();it!=vec.end();+it)
{
if(mp.count(it->getKey())
{
打破
}
}
我的问题是:有什么方法可以在一行中完成,比如

//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);
//这不起作用,因为count接受key\u类型
vector::iterator it=find_if(vec.begin(),vec.end(),boost::bind(&map::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;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
甲级{
公众:
A(常量std::字符串和键)
:key(key){}
std::string getKey(){return key;}
私人:
std::字符串键;
};
int main(int argc,const char*argv[]{
map mp=boost::assign::map_list_of(“Key1”、“Val1”)(“Key2”、“Val2”)(“Key3”、“Val3”);
vector vec=boost::assign::list_of(“AAA”)(“Key2”)(“BBB”);
//vector::iterator it=find_if(vec.begin(),vec.end(),boost::bind(&map::count,mp,boost::bind(&A::getKey,_1))!=0);
向量::迭代器;
for(it=vec.begin();it!=vec.end();+it)
{
if(mp.count(it->getKey())
{
打破
}
}

cout在C++11中,使用lambda:

find_if(vec.begin(), vec.end(), [&](A const & a){return mp.count(a.getKey());});

但是由于您使用的是Boost.Assign而不是统一初始化,也许您不能这样做。恐怕我不知道如何单独使用
bind
构造这样的函子。

您的解决方案很接近,只有一个右括号太多了。将每个括号放在一个新行上,每个级别都缩进删除无效括号:

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);

但是,考虑这样一个简单操作的可读性。如果一个简单的<<代码> < /Cult>循环不是通用的和可重用的,那么考虑把它隐藏在一个方便的函数中:

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)
);
模板
输入计算器查找\u(如果\u包含)(
输入者优先,
最后输入,
集装箱运输公司,
Fn(Fn)
{
while(第一个!=最后一个)
{
如果(0!=容器计数(fn(*first)),则首先返回;
++第一,;
}
最后返回;
}
...
向量::迭代器it=find_如果_包含(
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和容器,Fn-Fn)
:容器(和容器),fn(fn)
{}
模板
布尔运算符()(T&T)
{
返回0!=容器->计数(fn(t));
}
常数C*容器;
Fn Fn_;
};
模板
包含谓词
包含(常数C和容器,Fn)
{
返回包含_谓词(container,fn);
}
...
vector::iterator it=find_if(vec.begin(),vec.end(),
包含(mp,boost::bind(&A::getKey,_1));

我希望我能。但是我使用C++的以前版本。@亚历克斯:在这种情况下,我会坚持< <代码> > < /Calp>循环。即使你找到了一个合适的<代码> BION/CODE表达式,它也将是不可读的。嗨,这是有效的。我相信问题不是在括号的数量上,而是在…& MP……我错过了& &亚历克斯:很高兴它对你有用。通过值而不是指针传递
mp
只是一种优化,因为
mp
可以被复制构造。问题是额外的括号。在线编译器失败,因为它找不到
运算符!=
使用迭代器(从
如果
查找\ u返回)和int(
0
)。删除额外的括号会导致
!=0
使用
boost::bind
运算符重载,而不是尝试与
find_if
的返回值进行比较。
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)));