Why use mem_fn? - c++

I'm confused as to why std::mem_fn is needed.
I have a function that takes in any callable (lambda, function pointer, etc),and binds it to an argument.
Eg:
template<class T>
void Class::DoBinding(T callable) {
m_callable = std::bind(callable, _1, 4);
}
//somewhere else
Item item;
m_callable(item);
All code samples I've seen do:
//some defined member function
Item::Foo(int n);
DoBinding(std::mem_fn(&Item::Foo));
Why can't it simply be:
DoBinding(&Item::Foo);
It seems the latter is callable without having to use std::mem_fn, so why is it needed?

This is because generic code that expects UnaryFunction or BinaryFunction will invoke it directly with the regular call syntax. So to pick an arbitrary algorithm like for_each, it could well be implemented like:
template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
for (; first != last; ++first) {
f(*first); // <== N.B. f(*first)
}
return f;
}
If you called for_each() with &Item::Foo, the code try to call (&Item::Foo)(x), which is ill-formed since for pointers to members you have to write (x.*&Item::Foo)(). It's that syntactical difference that mem_fn is meant to solve: mem_fn deals with the invocation syntax of pointers to members so that you can use all the algorithms with pointers to members as well as functions and function objects. You cannot have for_each(v.begin(), v.end(), &Item::Foo) but you can have for_each(v.begin(), v.end(), mem_fn(&Item::Foo)).
This works just fine in std::bind() (and std::thread and std::function and ...) natively since those all have explicit handling for pointers to members separately. And since DoBinding() itself calls std::bind(), there is no reason for std::mem_fn in this case.
There is was a proposal to get rid of this syntactic difference: P0312. It did not go well.

This is usually done because the person who writes DoBinding(std::mem_fn(&Item::Foo)) has no idea that DoBinding can take a member pointer directly.
Remember: std::sort(..., &Item::Foo) will fail, because sort expects the value to be a directly-callable function object. And member pointers are not. Indeed, pretty much every algorithm in the C++ standard library will fail when given a member pointer instead of a directly-callable type. Your DoBinding only works because you're using std::bind, which has a special overload for member pointers. The caller of DoBinding doesn't necessarily know you're doing that.
Most code that takes callables by template parameters will choke on a member pointer. So to be safe, we don't pass member pointers around as objects that can be directly called; use mem_fn to turn it into such an object.

Related

Points to member variables and templating

I am currently using a templated function to evaluate the derivatives of mathematical functions, like so
template <class func_type>
arma::mat matrixDerivative
(func_type func, const double x, double h, double b=1.4) {
// <implementation details>
}
The template parameter allows me to use either function pointers or functors to evaluate the right-hand side.
Is there an easy way to extend this to evaluate the derivatives of functions that are class methods? I wasn't able to wrap my head around the use of function pointers to member functions and I couldn't work out the details of having a functor as a class attribute that still had access to its parent's attributes and methods.
My questions usually aren't clear, so feel free to ask for clarifications in the comments before answering.
In C++11 simply use a lambda:
[&]( double x )->double {
return ptr->method(x);
}
which generates a function object that can be invoked with double. The above construct assumes that the lambda will be used and discarded before the end of the current scope ([&] is unsafe otherwise).
Note that ->double can be omitted for single-line and void returning lambdas in C++11, and omitted even on multi-line lambdas in C++1y if you are ok with the return type it deduces (based off the first return statement in your function).
In C++03, std::mem_fun can be used, or you can create a custom function object.
In C++1y:
[&](auto&&... x) {
return ptr->method(std::forward<decltype(x)>(x)...);/
}
creates a perfect-forwarding functor wrapper. I would rarely do that kind of thing, even in C++1y, outside of seriously industrial library code. Less verbose we get:
[&](auto&&... x) {
return ptr->method(x...);
}
which lets us imperfectly forward, and defer selection of the overload to the point of use of the lambda, not the point where the lambda was written, which can be nice. (if any of the methods use rvalue or by-value calls, going back to perfect forwarding becomes tempting)
In C++11, std::mem_fn requires that the method in question not be overloaded, or that the overload be manually resolved (with an arcane-looking cast). std::bind then wraps that with a perfect-forwarding function object. The main advantage this procedure is is that the type of the construct, while implementation defined, can be determined, so you can have a function that returns the type in question. However, that is a pretty esoteric advantage: I would go with the lambda.
Lambdas, while strange, are increasingly common in C++, and are easier to understand what they are doing than a chain bind mem_fun expression in my experience as they look more like "normal" code (after you get over the "magic").

What is the correct argument type for a function-object?

I have a templated function that receives function-objects. Sometimes the function-objects are stateless structs, but sometimes they are large statefull objects. The state of the function-object is not changed in this function, only examined. I'm also very keen on writing code that the compiler can optimize as much as possible. What should I consider when choosing the argument type?
The function is of this type:
template<typename funcT>
auto make_particle(funcT fun) {
Particle<typename funcT::result_type> particle;
particle = fun();
return particle;
}
The argument type should probably be funcT const & fun so that the large objects are not copied, but why do most people use call-by-value function objects? Do I loose something by using const reference? Or should I use lvalue-reference? Please note that c++1y is ok and that the code example above is just an example.
There are several use cases, which should all be available:
The functor has no state and is supplied as a temporary: make_particle(MyFun())
The functor has a state which needs to be recovered later: YourFun f; make_particle(f);
You cannot solve both cases with one single reference type parameter: The first case requires a const lvalue reference or an rvalue reference, which forbids the second use, and the second case requlres an lvalue reference, which forbids the first use.
A common idiom in such situations is to accept the functor by value, and return it at the end:
template <typename Iter, typename F>
F map(Iter first, Iter last, F f)
{
// ... f(*first) ...
return f;
}
That may not be entirely applicable in your case, though, but it's an idea. For example, you could return a std::pair<ParticleType, F>. In any case you'd require your functor type to be copyable, but that's a reasonable requirement.
An alternative, helpfully pointed out by #Xeo, and available for function templates only, is to take the functor argument by universal reference, which will work in both cases:
template <typename Iter, typename F>
void map(Iter first, Iter last, F && f)
{
// ... use f(*first) ...
}
Note that in this case we do not use std::forward, since we are using f as a genuine reference, and not just to pass it through somewhere else. In particular, we are not allowed to move-from f if we still plan to use it.
The argument type should probably be funcT const & fun so that the
large objects are not copied,
That is not the view taken by the algorithms in the standard libraries. There, callable objects are taken by value. It's up to the author of the callable object to ensure that it's reasonably cheap to copy. For example if it needs access to something large, then you can have the user of the functor provide a reference to one and store that in the functor -- copying a reference is cheap.
Now, it may be that you want to do things differently from the standard library because you expect particle-making functions to be unusually difficult to make cheap to copy or move. But C++ programmers are familiar with functors being copied, so if you do what the standard library does then usually you aren't making their lives any worse than they were already. Copying functors isn't an issue unless you make it one :-)

What is the correct type of boost::mem_fn?

Am I able to implement the following function in C++?
I would like to keep the myInstance variable unspecified until the callback method is called, instead of containing it in a boost::bind instance.
MyClass *myInstance;
void call(/* boost::mem_fn */ callback)
{
// Somewhere in this function, the operator()() method
// is called on the callback instance
callback(myInstance);
}
call(boost::mem_fn(&MyClass::myMethod));
I understand that boost::mem_fn is a function which returns a particular object, but I'm unsure of its type. The documentation says unspecified as its return type. One of the boost::bind constructors takes this type as a parameter, but I'm unable to find the actual declaration in its implementation. Also, am I even allowed to store my own instance of this particular type, or is this strictly for use by boost functions?
This is one of those cases where it seems that the compiler is doing some very magic stuff.
The reason there isn't really a well defined type is that the type returned from bosst::mem_fn is always assumed to be a template parameter of the function it's passed to. Let me show you an example:
std::for_each has a signature like this:
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f);
This little slice of magic has two template parameters, an InputIterator and a Function. These could have been called anything, but the names given to them describe how they will be used, really, are more self-documenting names than a real type. The type of InputIterator may well be something like std::vector<foo>::iterator - the point is that the compiler will automatically resolve what an "InputIterator" is at compile time. It can figure this type out for you.
The same is true of Function. As long as you pass it something that can be called - that is, has a version of operator() that is compatible with what gets called in for_each, then you never need to know what Function is.
So the short answer is, make your call function take a template parameter:
template<typename SomeSortOfFunction>
void call(SomeSortOfFunction callback)
and then the compiler should resolve SomeSortOfFunction to be whatever the type is that is returned from boost::mem_fn
The return type of boost::mem_fn is unspecified. You should use either Matt's approach (i.e. pass it as a template), or if separate compilation is important to you, use type erasure:
MyClass *myInstance;
void call(boost::function<void(MyClass*)> callback)
{
callback(myInstance);
}
call(boost::mem_fn(&MyClass::myMethod));
The return type of mem_fn is not something you should ever explicitly type or store. It is generated at compile time via the types of the arguments.
It can, however, be stored via std::function (or boost::function).
The operator() signature of men_fn is the original method arguments with a possibly const pointer to the class prepended, and the same return value type. Just create a std::function with that signature, and it can take the men_fn type and store it.
In short if you have a zero argument method for class foo that returns void try storing the men_fun in a std::function<void(foo *)>.

Difference between std::function<> and a standard function pointer? [duplicate]

This question already has answers here:
Should I use std::function or a function pointer in C++?
(6 answers)
Closed 5 years ago.
Whats the difference between std::function<> and a standard function pointer?
that is:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Are they effectively the same thing?
A function pointer is the address of an actual function defined in C++. An std::function is a wrapper that can hold any type of callable object (objects that can be used like functions).
struct FooFunctor
{
void operator()(int i) {
std::cout << i;
}
};
// Since `FooFunctor` defines `operator()`, it can be used as a function
FooFunctor func;
std::function<void (int)> f(func);
Here, std::function allows you to abstract away exactly what kind of callable object it is you are dealing with — you don't know it's FooFunctor, you just know that it returns void and has one int parameter.
A real-world example where this abstraction is useful is when you are using C++ together with another scripting language. You might want to design an interface that can deal with both functions defined in C++, as well as functions defined in the scripting language, in a generic way.
Edit: Binding
Alongside std::function, you will also find std::bind. These two are very powerful tools when used together.
void func(int a, int b) {
// Do something important
}
// Consider the case when you want one of the parameters of `func` to be fixed
// You can used `std::bind` to set a fixed value for a parameter; `bind` will
// return a function-like object that you can place inside of `std::function`.
std::function<void (int)> f = std::bind(func, _1, 5);
In that example, the function object returned by bind takes the first parameter, _1, and passes it to func as the a parameter, and sets b to be the constant 5.
They are not the same at all. std::function is a complex, heavy, stateful, near-magic type that can hold any sort of callable entity, while a function pointer is really just a simple pointer. If you can get away with it, you should prefer either naked function pointers or auto-bind/auto-lambda types. Only use std::function if you really need a systematic way of organizing a heterogeneous collection of callable entities, such as functions, functors, capturing lambdas and bind expressions.
Update: A bit of explanation about auto types: Compare the following two functions:
void do_something_1(std::function<void(int)> f, int a) { f(a); }
template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
Now imagine invoking them with a lambda or a bind expression:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12);
do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
The second version with the template is more efficient, because in both cases, the argument F is deduced to the actual, unknowable type of the expression. The first version, with std::function, isn't a template and may look simpler and more deliberate, but it always forces the construction of the std::function object, and quite possibly carries multiple type erasure and virtual dispatch costs.
A std::function has state. It can hold additional parameters "bound" into it.
These parameters can range from things like other classes, other functions, or even this pointers for member function calls.
The replacement function pointer is not typedef int (*fn)(int);
It is typedef int (*fn)(void*,int);, with the void* reperensting the state that would be hidden in the std::function.
No.
One is a function pointer; the other is an object that serves as a wrapper around a function pointer.
They pretty much represent the same thing, but std::function is far more powerful, allowing you to do make bindings and whatnot.

Why doesn't unary_function define operator()?

I was just looking for a handy base class for a set of functors to be based on taking and int and returning void.
Thinking to use std/functional the functors are basically going to be unary_function<int,void> with operator().
Why is virtual result_type operator()(const argument_type& _Left) const = 0; not defined on the unary_function template? I'm guessing that it's because there could be variations in constness...
Is there some other template I've missed that includes the operator()?
I haven't done this in a while, am I missing something?
How would I also make use of existing functional like
std::ptr_fun< HWND, void >(someFunction);
std::pointer_to_unary_function<HWND, void>(someFunction);
EDIT:
Perhaps I should include the other half of the usage to make this complete. Maybe it's the usage half that is not fitting in with the concept.
How would one pass the functor to a method and use it?
typedef unary_function<int,void> Functor;
void DoStuff(const Functor& functor) {
int demo = 1;
functor(demo);
}
functor as a unary_function doesn't define operator() and so DoStuff doesn't compile.
Template concepts are duck-typed. The fact that a class satisfying the UnaryFunction concept needs operator() is specified in the documentation and inferred from the templates which use template parameters satisfying that concept. There's no need to spell out the function signature, or to require that it be virtual, that it take a const reference parameter, or that it be a const member function.
The unary_function template should not be thought of as an interface (and it isn't designed as one). It's certainly not a polymorphic base class. It's a helper, which is used by classes that wish to implement the AdaptableUnaryFunction concept.
From the STL docs, which are reliable for the original design rationale: "the only reason it exists is to make defining Adaptable Unary Functions more convenient" - http://www.sgi.com/tech/stl/unary_function.html
The standard is similar: "The following classes are provided to simplify the typedefs of the argument and result types" (20.3.1/1)
Advanced usage - actually what's required for UnaryFunction is that if f is a unary function object, and x is convertible to the argument type, then f(x) is a valid expression of the result type. It needn't have a one-argument operator() at all, it's fine to have a two-arg operator() with the second arg having a default value. Try defining that as a pure virtual function ;-)
Second question, you make use of ptr_fun just by calling it with function name/pointer. Its template parameters will be inferred from the function type, so you don't need to specify them. The result is an object of the corresponding pointer_to_unary_function template type.
To use the example straight from the STL docs:
transform(first, last, first,
compose1(negate<double>, ptr_fun(fabs)));
This is approximately equivalent to:
for (auto current = first; current != last; ++current) {
*current = -fabs(*current);
}
(where I use auto in its C++0x sense, meaning "I cannot be bothered / it is impossible to write the iterator type here")
A function name/pointer can be used in transform (which takes a UnaryFunction template parameter), but not in compose1 (which takes an AdapatableUnaryFunction template parameter). So without ptr_fun, there's no way to compose negate with fabs.
In response to your Edit, I stress, unary_function is not a polymorphic base class. You cannot usefully use it (or any of its instantiations) as a function parameter type.
If you want to use the UnaryFunction or AdaptableUnaryFunction concepts, then you must write a function template:
template <typename UnaryFunction>
void DoStuff(UnaryFunction &functor) {
int demo = 1;
functor(demo);
}
This only requires that the functor take a type which int converts to, though. It doesn't require that it take exactly int and return exactly void. That's usually an advantage.
If a template doesn't do what you want, then unary_function is not for you. You haven't missed anything: you can design your own interface with a virtual operator(), but the standard libraries don't aim to provide any such thing.
Because a virtual operator () is not a part of the unary_function concept. The unary function concept can have a non-virtual operator in addition to differences in constness.