试图查看vector <string>在map <string,string>中是否没有值

SWK*_*WKK 3 c++ boost bind

只是为了好玩,我试图用带有boost :: bind的std :: find_if编写一行,以检查地图中向量中给出的所有键是否都没有值,但实际上无法提供一个整齐的代码行.
这是我的尝试

vector<string> v;  
v.push_back("a");  
v.push_back("2");  
...  
map<string, string> m;  
m.insert("b","f");  
...  
std::find_if(v.begin(), v.end(), boost::bind(&string::empty, boost::bind(&map<string,String>::operator[], _1), _2 )) != v.end();  
Run Code Online (Sandbox Code Playgroud)

显然这是一个很大的失败......有人试过这样的事吗?

Pup*_*ppy 5

std::for_each(v.begin(), v.end(), [](std::string& ref) { if m.find(ref) != m.end() /* do something*/ });
Run Code Online (Sandbox Code Playgroud)

Lambdas ftw.

  • 但他的回答不是一行代码! (2认同)

Kir*_*sky 5

true仅当以下所有元素v都不存在时,以下代码行才会返回m:

bool a = v.end() == std::find_if( v.begin(), v.end(), boost::bind( &str_map_t::const_iterator::operator!=, boost::bind<str_map_t::const_iterator>( &str_map_t::find, &m, _1 ), m.end() ) );
Run Code Online (Sandbox Code Playgroud)

说明:

这里我们有两个仿函数:

  1. boost::bind<str_map_t::const_iterator>( &str_map_t::find, &m, _1 )
    如果没有找到, 该仿函数将返回const_iterator指向元素的指向m或指向的元素m.end().在这里,你应该明确地指向返回类型str_map_t::const_iteratorboost::bind摆脱模糊性.

  2. boost::bind( &str_map_t::const_iterator::operator!=, _1, _2 )
    true如果_1!=_2false其他情况, 这个将返回.

结合1和2,我们将获得完整的代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <map>    
#include <boost/bind.hpp>    
using namespace std;

int main(int argc, char *argv[])
{
    vector<string> v;
    v.push_back("x");
    v.push_back("a");
    v.push_back("6");

    typedef map<string, string> str_map_t;
    str_map_t m;
    m.insert( str_map_t::value_type( "b", "f" ) );

    bool a = 
      v.end() == std::find_if( 
        v.begin(), v.end(), 
          boost::bind( 
            &str_map_t::const_iterator::operator!=, 
            boost::bind<str_map_t::const_iterator>( &str_map_t::find, &m, _1 ), 
            m.end() 
          ) 
      );

    std::cout << a << endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不会说它是可读代码,我建议编写一个自定义仿函数,以使其更具可读性.更易读的版本可能如下所示(不含bind):

struct not_in_map {
    not_in_map( const str_map_t& map ) : map_(map) {}
    bool operator()( const string& val ) { return map_.end() != map_.find( val ); }
private:
    const str_map_t& map_;
};
bool a = v.end() == std::find_if( v.begin(), v.end(), not_in_map(m) );
Run Code Online (Sandbox Code Playgroud)

  • 是的,我不会让这些代码看到日光,但仍然想学习这些漂亮的功能.谢谢你的回答. (2认同)