2

我不知道如何将命名函数作为参数发送给另一个函数,并将该参数包含在 phoenix lambda 表达式中。

这是我能想到的最小示例。

#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/phoenix.hpp>

using namespace std;
namespace ph = boost::phoenix;
using ph::arg_names::arg1;

template <typename Predicate>
void foo(vector<int> &v, Predicate p) {
  for_each(v.begin(), v.end(),
      if_(p(arg1))
      [
        cout << "found " << arg1 << ", "
      ]);
  cout << endl;
}

bool is_odd(int i) {
  return (i % 2 == 1);
}

main() {
  vector<int> v(10);
  int i = 1;
  generate(v.begin(), v.end(), ph::ref(i)++);
  cout << "looking for odd ones ";
  foo(v, arg1 % 2 == 1);

  cout << "using named function ";
  //foo(v, is_odd);
  //foo(v, &is_odd);
  //foo(v, ph::bind(&is_odd, arg1));
  //foo(v, boost::bind(&is_odd, _1));
}

我不知道如何将is_odd()函数foo()作为谓词发送。

注意: 在我的实际代码中,谓词实际上是arg1( arg1is of的成员函数class Bar,我需要Bar::is_odd作为谓词)。我尝试过这种(arg1->*&Bar::is_odd)()风格,但没有奏效。为了简单起见,我没有在这个例子中包括这个。

更新: 这是相同代码的 C++11 版本。这个效果很好,但是,我想让它与 phoenix 一起使用,因为我不能使用 C++11

#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

template <typename Predicate>
void foo(vector<int> &v, Predicate p) {
  for_each(begin(v), end(v),
      [&] (int i) {
        if (p(i))
          cout << "found " << i << ", ";
      });
  cout << endl;
}

bool is_odd(int i) {
  return (i % 2 == 1);
}

main() {
  vector<int> v={1,2,3,4,5,6,7,8,9,10};
  cout << "looking for odd ones ";
  foo(v, [] (int i) {return (i%2 == 1);});

  cout << "using named function ";
  foo(v, &is_odd);
}
4

1 回答 1

1

可能有另一种更简单的方法可以做到这一点,但另一种方法是使用 phoenix 函数(在没有 -std=c++11 的 g++ 4.8.1 上测试):

#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/phoenix.hpp>

using namespace std;
namespace ph = boost::phoenix;
using ph::arg_names::arg1;

bool is_odd(int i) {
  return (i % 2 == 1);
}

struct is_odd_impl
{
  template <typename Sig>
  struct result;

  template <typename This, typename Arg>
  struct result<This(Arg)>
  {
    typedef bool type;
  };

  template <typename Arg>
  bool operator()(const Arg& arg) const
  {
    return is_odd(arg);
    //return arg.is_odd();
  }
};

ph::function<is_odd_impl> lazy_is_odd = is_odd_impl();

template <typename Predicate>
void foo(vector<int> &v, Predicate p) {
  for_each(v.begin(), v.end(),
      if_(p(arg1))
      [
        cout << "found " << arg1 << ", "
      ]);
  cout << endl;
}



int main() {
  vector<int> v(10);
  int cont = 1;
  std::generate(v.begin(),v.end(),ph::ref(cont)++);

  cout << "looking for odd ones ";
  foo(v, arg1 % 2 == 1);

  cout << "using named function ";
  foo(v, lazy_is_odd);
}
于 2013-08-28T17:45:40.253 回答