11

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.

Daniel Heilper
  • 1,182
  • 2
  • 17
  • 34
Fanatic23
  • 3,378
  • 2
  • 28
  • 51

4 Answers4

8

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.

josephthomas
  • 3,256
  • 15
  • 20
  • +1. That is the kind of thing I want to try too. You have more details to share on how you did the reflection bit? – Fanatic23 Apr 14 '12 at 21:02
  • Hmm, this was basically the most I could describe without probably putting up the entire codebase on github or something (and the code is closed source). I updated my post to provide more details though. Unfortunately, there is not a lot of documentation for the type of system I developed here. I am in the process of writing a large document on the entire system, but its not quite finished yet. I can say I have been using `std::mem_fn` and `std::bind` for this kind of thing for nearly two years though with no problems. – josephthomas Apr 14 '12 at 21:07
  • Also not, that this is one of the most complex usages of `mem_fn` and `bind` that I know of. If you are looking to get practice using the two types, perhaps you should look at some small usages of them (I did at first before I developed this system). This reflection system is built around the use of these two types (and `std::function`). Although honestly, this may be able to be just replaced with member function pointers (in theory). They both have their advantages and disadvantages. – josephthomas Apr 14 '12 at 21:16
5

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.)

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
4

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;
}
Philipp
  • 48,066
  • 12
  • 84
  • 109
0

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.