3

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

struct T
{
   int x;
   bool y;
};

和一个这样的容器:

std::vector<T> v;

以及一种强烈的渴望——在一个单一的声明中v——是否有任何元素y == true。这可能涉及std::find_if.

我的理解是std::bindandboost::bind是针对成员函数的,不能应用于成员数据。


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

  • 比较函数/函子
  • 循环

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

  • 拉姆达斯
4

2 回答 2

9

我的理解是std::bindandboost::bind是针对成员函数的,不能应用于成员数据。

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

文档中

指向成员函数的指针和指向数据成员的指针不是函数对象,因为它们不支持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:已找到

于 2013-06-19T16:37:07.917 回答
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();
于 2013-06-19T16:59:00.397 回答