Fanatic23
Fanatic23

Reputation: 3428

some practical uses of mem_fn & bind

Can someone recommend some cool practical uses of tr1's mem_fn and bind utilities? I don't need esoteric c++ for library development. just some application level coding which makes uses of these.

any help will be very appreciated.

Upvotes: 11

Views: 8581

Answers (4)

Dr. Knowbody
Dr. Knowbody

Reputation: 1

One issue is that lambdas have difficulty using methods from forward declared classes. I've used bind to make use of member functions that use methods from a forward declared class. I couldn't find a solution that used lambdas. Here was the scenario: I had a list of member functions, f1, f2, ... defined in class A, some of which used methods from a forward declared class. I wanted to be able to flexibly swap out operators of the nodes of an expression tree, class B, with any one of these fi functions. In B, a generic operator was defined. I used bind to associate the fi functions to the generic operator adaptively. That way, the fi member function definitions could be prototyped in a A.h file where the forward declaration was put, then the implementations for the fi functions could be put in the A.cpp file and accessed by B class. I'd be curious if others have run into this issue and how they dealt with it.

Upvotes: 0

josephthomas
josephthomas

Reputation: 3276

I have used std::mem_fn and std::bind for reflection style properties.

So I would have a class SomeClass with a vector of AbstractProperty. There can be several different types of classes from AbstractProperty, such as PropertyFloat, PropertyU32, etc.

Then in SomeClass I will bind to a std::function for AbstractProperty. I would bind by doing

std::bind(std::mem_fn(&SomeClass::SomeFloatGetter), this)

For a setter type function, I would use

 std::bind(std::mem_fn(&SomeClass::SomeSetterGetter), this, std::placeholders::_1)

Of course, to set the functions to the class is more difficult, but I do use a std::function to do so. In PropertyFloat I have

typedef std::function<float(void)> GetterType;

So it set it via a function, I would pass the first std::bind I showed as the parameter for

typename PropertyFloat::GetterType getter

Of course, the types could make use of templates and be more generic, but that is a trade off depending on what you are developing for.

Upvotes: 8

Philipp
Philipp

Reputation: 49850

The following code counts the number of elements greater than five:

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

int main() {
  using namespace std;
  vector<int> v { 1, 5, 2, 7, 6, 7, 5 };
  cout << count_if(v.begin(), v.end(),
                   bind(greater<int>(), placeholders::_1, 5)) << endl;
}

Upvotes: 4

Some programmer dude
Some programmer dude

Reputation: 409452

Normally it can be quite a hassle to use member functions for callbacks, for example for use in the <algorithm> functions. std::mem_fn (it's been standardized now, so you shouldn't need to use the tr1 namespace anymore) creates a callable object that can be used as the functor object of those functions. For an example of its use, see the examples section of this link which uses std::string::size.

std::bind can be used when e.g. you don't know the actual arguments at compile-time, but have to create a callable object with arguments runtime. It can also be used to reorder arguments, example:

auto f1 = std::bind(printf, _2, _1);
f1(42, "%d\n");

(Okay, stupid example, but all I could think of right now.)

Upvotes: 5

Related Questions