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

时间:2010-06-24 18:51:43

标签: c++ boost bind

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

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

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

3 个答案:

答案 0 :(得分:5)

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

Lambdas ftw。

答案 1 :(得分: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() ) );

<强>解释

这里我们有两个仿函数:

  1. boost::bind<str_map_t::const_iterator>( &str_map_t::find, &m, _1 )
    如果找不到,该仿函数将返回const_iterator指向mm.end()的元素。在这里,您应明确指出str_map_t::const_iterator的返回类型boost::bind以消除歧义。

  2. boost::bind( &str_map_t::const_iterator::operator!=, _1, _2 )
    如果true_1!=_2,则会返回false

  3. 合并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;
    }
    

    我不会说它是可读代码而且我建议编写一个自定义仿函数以使其更具可读性。更易读的版本可能如下所示(没有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) );
    

答案 2 :(得分:1)

boost :: lambda是你最好的选择,直到C ++ 0x,他们和其他有用的函数编程机制将成为语言的一部分,但如果你在一个团队中工作,我建议稍微减少你的代码。

尽管这些代码简洁明了,但对于经验不足的C ++编码人员来说却很难说,他们无法理解函子,谓词等。即使在那些代码中,它也会让人头疼,试图调试代码由于其分散性。我不得不牺牲C ++的所有这些更简洁的功能方面,支持使用迭代器的简单for循环,只是为了我所使用的团队的整体利益。也许使用C ++ 0x,其他程序员在函数式编程方面遇到的问题可能会减少到可以轻松理解的地方,并且没有复杂的模板机制,很多人似乎(不幸的是)厌恶。