如何使用 std::bind with compose2.

How to use std::bind with compose2?

本文关键字:with compose2 bind std 何使用      更新时间:2023-10-16

我想在 C++11 的compose2中使用binary_function,而不使用booststd::bind

编辑:或拉布达斯。

假设我有以下定义:

bool GreaterThanFive(int x) { return x > 5; }
struct DivisibleByN : binary_function<int, int, bool> {
  bool operator()(int x, int n) const { return x % n == 0; }
};

假设我想计算一个向量的元素,这些元素大于 5 且能被 3 整除。我可以轻松地将它们与以下内容相结合:

int NumBothCriteria(std::vector<int> v) {
  return std::count_if(v.begin(), v.end(),
                       __gnu_cxx::compose2(std::logical_and<bool>(),
                                           std::bind2nd(DivisibleByN(), 3),
                                           std::ref(GreaterThanFive)));
}

由于bind2nd在 C++11 年已弃用,我想移至 std::bind .我还没有弄清楚为什么以下内容不等效(并且不编译(。

int NumBothCriteria(std::vector<int> v) {
  using namespace std::placeholders;
  return std::count_if(v.begin(), v.end(),
                       __gnu_cxx::compose2(std::logical_and<bool>(),
                                           std::bind(DivisibleByN(), _1, 3),
                                           std::ref(GreaterThanFive)));
}

它给了我以下编译错误:

no type named 'argument_type' in 'std::_Bind<DivisibleByN *(std::_Placeholder<1>, int)>`
  operator()(const typename _Operation2::argument_type& __x) const
                   ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~

我的直觉是,std::bind没有做std::bind2nd做的事情,但我不确定如何让argument_type typedef恢复。

我的搜索提出了三个问题。第一个使用bind2nd,第二个使用boost,第三个用于C++03。不幸的是,有效的STL仍然使用std::bind2nd

只是不要使用bindcompose2。你以后会感谢自己:

int NumBothCriteria(std::vector<int> v) {
  return std::count_if(v.begin(), v.end(),
                       [](int i){ return i > 5 && i%3 == 0; });
}
<小时 />

您正在寻找的答案是,您可以简单地使用std::bind代替您使用__gnu_cxx::compose2的位置:

return std::count_if(v.begin(), v.end(),
    std::bind(std::logical_and<bool>(),
        std::bind(DivisibleByN(), _1, 3),
        std::bind(GreaterThanFive, _1)));

但这比仅仅使用 lambda 要复杂得多,也更难推理。

我想出了如何让它与std::function一起工作。

int NumBothCriteria2(std::vector<int> v) {
  using std::placeholders::_1;
  return std::count_if(v.begin(), v.end(),
                       __gnu_cxx::compose2(std::logical_and<bool>(),
                                           std::function<int(int)>(std::bind(
                                               DivisibleByN(), _1, 3)),
                                           std::ref(GreaterThanFive)));
}