【问题标题】:How can I search a container of objects for a data member value?如何在对象容器中搜索数据成员值?
【发布时间】:2013-06-19 16:37:07
【问题描述】:

我有一个像这样的对象类型:

struct T
{
   int x;
   bool y;
};

还有一个像这样的容器:

std::vector<T> v;

并且强烈渴望确定 - 在单个语句中 - v 的任何元素是否具有 y == true。这可能涉及std::find_if

我的理解是std::bindboost::bind是针对会员功能的,不能应用于会员数据。


因为我不喜欢他们,所以我希望避免:

  • 比较函数/函子
  • 循环

因为我的环境是C++03,所以以下的不可用:

  • lambdas

【问题讨论】:

    标签: c++ boost boost-bind c++03


    【解决方案1】:

    我的理解是std::bindboost::bind是针对会员功能的,不能应用于会员数据。

    值得注意的是,事实并非如此! boost::bind 将愉快地绑定到成员数据,并允许您在“内联迭代”期间对其执行操作。

    来自the documentation

    指向成员函数的指针和指向数据成员的指针不是函数对象,因为它们不支持operator()。为方便起见,bind 接受成员指针作为其第一个参数,其行为就好像 boost::mem_fn 已用于将成员指针转换为函数对象。换句话说,表达式

    bind(&X::f, args)
    

    等价于

    bind<R>(mem_fn(&X::f), args)
    

    其中 RX::f 的返回类型(对于成员函数)或成员的类型(对于数据成员。)

    另外,来自boost::mem_fn 的文档:

    mem_fn 还支持指向数据成员的指针,将它们视为不带参数的函数并返回对成员的 (const) 引用。

    所以,你可以这样做:

    #include <vector>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <boost/bind.hpp>
    
    struct T
    {
       int x;
       bool y;
    };
    
    void f(const std::string& name, const std::vector<T>& v)
    {
       const bool found = std::find_if(
          v.begin(),
          v.end(),
          boost::bind(&T::y, _1) == true
       ) != v.end();
    
       std::cout << name << ": " << (found ? " FOUND" : " not found") << '\n';
    }
    
    int main()
    {
       T a = { 0, false };
       T b = { 1, false };
       T c = { 2, true  };
    
       std::vector<T> v;
       f("a", v);
    
       v.push_back(a);
       v.push_back(b);
       f("b", v);
    
       v.push_back(c);
       f("c", v);
    }
    

    输出:

    a:未找到
    b: 未找到
    c: 找到

    【讨论】:

    • 啊,太棒了!这是一个令人愉快的惊喜。谢谢
    【解决方案2】:

    您想要的(确定 — 在单个语句中 — v 的任何元素是否具有 y == true)似乎是:

    inline bool y_is_true(std::vector<T>::iterator i) { return i->y; };
    

    (在你的功能之外)和

    bool found = std::find_if(v.begin(), v.end(), y_is_true) != v.end();
    

    另一种选择是使用boost::lambda

    bool found = std::find_if(v.begin(), v.end(), _1.y) != v.end();
    

    【讨论】:

    • 定义函子然后执行搜索是两个语句。但是,boost::lambda 的方法非常有趣,我将不得不研究一下!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-02-12
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多