简体   繁体   中英

std::bind member function within struct

I have a function bar that is widely applicable, and not a member of any struct . bar takes a functional/function pointer and some other arguments.

I also have many structs. They are heterogeneous in member variables.

Within each struct Foo , I want a member function of Foo to call on bar such that the functional supplied to bar is another non-static member function of Foo .

The many posts on SO related to std::bind with member functions but they seem slightly different.

#include <functional>
using namespace std;

typedef  vector<int>  V;

V bar(function<int(V)> f , V a) {
  // do work.
}

struct Foo
{
    V x;

    int f1(V y , int z) {
       // do work that involves member variable x,
       // and inputs y, z.
    }

    int f2() {
        std::function<V(int)> wrapper = std::bind(f1 , _1 , 7);
        V a;
        V c = bar(wrapper , a);
        return accumulate(c.begin(),c.end(),0);
    }
};

The error is of course:

: error: invalid use of non-static member function

In general, don't use std::bind() . There are very few circumstances where a lambda won't replace it, and understanding how to use std::bind() to the point where you are never surprised is a large investment.

std::bind() was brought into the language from boost at the same time lambdas were, and it could handle a few corner cases that lambdas could not. By today, those corner cases are gone. It would not be added (especially in its current form) if proposed today.

Instead, learn how to use lambdas. Lambdas are about as hard to fully master as std::bind() , but are more powerful and useful today. So learn to use the better option.

int f2() {
  V a;
  V c = bar([&](V in){return f(v, 7);}, a);
  return accumulate(c.begin(),c.end(),0);
}

This particular pattern relies on bar not storing the std::function after the call.

The first (hidden) argument of a argument of a member function is the this variable. So the correct way to use std::bind here is

std::function<int(int)> wrapper = std::bind(&Foo::f1, this, _1 , 7);

However, modern C++, the correct way to do this is to use a lambda. I usually use explicit binds for this, so:

auto wrapper = [this](V v) {
  return f1(v, 7);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM