0

我正在用 C++ 编写代码。我有一个包含这么多文件的项目。我有一个名为 list 的对向量,如下所示:

std::vector< std::pair< structure1, double> > list;

我想检查一个特定的双精度值z是否存在一个元素:el在列表中,这样: el.second == z

我想用find_if

为此,我实现了一个方法:Scheduled它接受两个参数:第一个是存储在列表中的元素,第二个是要查找的特定值。我尝试了几种方法,但最终总是以第一种方式出现错误:

 bool classA::Scheduled(std::pair< structure1,double > const el, double const t )
{
  return el.second==t;

}

在另一个方法中但仍在同一个类中:classA

auto Scheduled1 = std::bind(&classA::Scheduled,this,_1,z);



 bool call=std::find_if(list.begin(),list.end(),Scheduled1)=!list.end();

此解决方案给出以下错误:

 error: ‘Scheduled1’ does not name a type

第二种方式:直接使用 lambda

bool call = std::find_if(list.begin(),list.end(),[this](std::pair<struct1,double> const& el){return el.second==z;})!=list.end();

z 是 classA 的成员变量第二种编码方式会导致此错误:

error: no matching function for call to 

'find_if(std::vector >::iterator, std::vector >::iterator, classA::method1(int)::__lambda0)'</p>

4

2 回答 2

4

没有必要 mix bindbind1st并且mem_fun这样做(后两者在 C++11 中已弃用);只需使用 lambda

bool call = std::find_if(list.begin(), list.end(),
                         [this](std::pair< strucure1,double > const& el) {
                           return el.second == z;
                         }) != list.end();

或者如果你想打电话Scheduled

bool call = std::find_if(list.begin(), list.end(),
                         [this](std::pair< strucure1,double > const& el) {
                           return Scheduled(el, z);
                         }) != list.end();

如果你必须使用bind

bool call = std::find_if(list.begin(), list.end(),
                         std::bind(&classA::Scheduled, this, _1, z)) != list.end();

在任何一种情况下,您都可能希望更改Scheduledstatic成员函数,因为它不需要访问任何非静态成员,在这种情况下,bind选项变为

bool call = std::find_if(list.begin(), list.end(),
                         std::bind(&classA::Scheduled, _1, z)) != list.end();

此外,Scheduled可能应该通过避免不必要的副本来进行std::pair论证。const&

另一种选择是使用any_of而不是find_if,这避免了将结果与结束交互器进行比较

bool call = std::any_of(list.begin(), list.end(),
                        <insert lambda or bind expression>);

这是对您的尝试有什么问题的解释。

auto Scheduled1=std::bind(Scheduled, _1, z);

Scheduled是一个非静态成员函数,这意味着它需要一个隐式的第一个参数,一个指向必须调用它的实例的指针,即this指针。此外,创建指向成员函数的指针的语法是&ClassName::MemberFunctionName. 所以上面的行应该是

auto Scheduled1=std::bind(&classA::Scheduled, this, _1, z);

bind返回一个未指定类型的函数对象,但您将该对象当作成员函数 ( mem_fun(&classA::Scheduled1)) 使用,这显然是不正确的。只需将上述Scheduled1对象作为示例中的第三个参数传递给即可find_if

于 2015-05-27T13:30:02.460 回答
0

正如@Praetorian 所提到的,您可以使用 lambdas。但是,绑定器允许人们开箱即用地使用现有的谓词函数,并且有时更具可读性(新的 std::bind 自动将成员函数绑定到实例这一事实,允许人们使用类型的公共接口盒子外面)。我添加了一个类似于您的示例(可以编译),我将在其中解释一些事情(参见代码注释):

#include <iostream>
#include <vector>
#include <utility>
#include <functional>
#include <algorithm>

// Replaces your structure...
struct Xs{};


// typedef so that we can alias the ugly thing...    
typedef std::vector<std::pair<Xs, double>> XDoubleVector;

// --- From your code, I've just named it A for brevity....
struct A
{
    bool Scheduled(std::pair<Xs,double> const el, double const t )
    {
      return el.second==t;
    }
};


int main() {

    using namespace std::placeholders;
    //Instantiate it.... replaced your list.
    XDoubleVector doubleVect;
    //--- and add some elements....

    //We need to instantiate A, in order to invoke 
    // a member function...
    A a;

    // Returns true if found...
    return std::find_if(
        doubleVect.begin(),
        doubleVect.end(),
        //Notes:
        //- Scheduled is a member function of A
        //- For that reason, we need to pass an instance of
        //   A to binder (almost seen as first bound).
        //- _1 indicates that the first parameter to Scheduled will be            
        //   passed in by algorithm
        //- We've hardcoded the second parameter (it is therefore 
        //   bound early).
        std::bind(&A::Scheduled, a, _1, 20.9)) != doubleVect.end();

}

问候,维尔纳

于 2015-05-27T14:05:35.247 回答