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").
Related
In the past, when I wanted a callback as a function parameter, I usually decided to use std::function. In rare cases where I definitely never use captures, I used a typedef for a function declaration instead.
So, usually my declaration with a callback parameter looks something like this:
struct Socket
{
void on_receive(std::function<void(uint8_t*, unsigned long)> cb);
}
However, as far as I know, std::function is actually doing a little work at runtime due to having to resolve the lambda with it's captures to the std::function template and move/copy it's captures (?).
Reading about the new C++ 20 features I figured I might be able to make use of concepts to avoid using std::function and use a constrained parameter for any viable functor.
And this is where my problem comes up: Since I want to work with the callback functor objects sometime in the future, I have to store them. Since I have no definitive type for my callback, my initial thought was to copy (eventuallty move at some point) the functor to heap and use a std::vector<void*> to note where I left them.
template<typename Functor>
concept ReceiveCallback = std::is_invocable_v<Functor, uint8_t*, unsigned long>
&& std::is_same_v<typename std::invoke_result<Functor, uint8_t*, unsigned long>::type, void>
&& std::is_copy_constructible_v<Functor>;
struct Socket
{
std::vector<void*> callbacks;
template<ReceiveCallback TCallback>
void on_receive(TCallback const& callback)
{
callbacks.push_back(new TCallback(callback));
}
}
int main(int argc, char** argv)
{
Socket* sock;
// [...] inialize socket somehow
sock->on_receive([](uint8_t* data, unsigned long length)
{
// NOP for now
});
// [...]
}
While this works well enough, when implementing the method that is supposed to call the functor, I noticed that I have just postponed the issue of the unknown/missing type. As far as my understanding goes, casting a void* to a function pointer or some similar hack should yield UB - How would the compiler know, that I am actually trying to call operator() of a class that is completely unknown?
I thought about storing the (copied) functor along with the function pointer to it's operator() definition, however I have no idea how I could inject the functor as this inside the function, and without it I doubt that captures would work.
Another approach I had was to declare a pure virtual interface that declares the required operator() function. Unfortunately my compiler forbid me to cast my functor to the interface and I don't think there is a legal way to let the lambda derive from it either.
So, is there a way to work this out or am I possibly just misusing the template requirements/concepts feature?
Your initial version used std::function precisely because it erases the type. If you want type erasure (and you clearly do, since you want the user to be able to use any type without your code knowing explicitly what that type is), then you need some form of type erasure. And type erasure isn't free.
Constraints are for templates. You don't want a template function; you want a single function that deals with a type-erased callable.
And for callbacks which have to outlive the call stack of the provider, std::function's overhead is pretty much what you need. That is, the "overhead" is not pointless; it's what permits you to store objects of arbitrary, unknown types in your callback processor.
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 :-)
I am playing around with the c++11 functional features. One thing I find odd is that the type of a lambda function is actually NOT a function<> type. What's more, lambda's do not seem to play really well with the type-inferencing mechanism.
Attached is a small example in which I tested flipping the two arguments of a function for adding two integers. (The compiler I used was gcc 4.6.2 under MinGW.) In the example, the type for addInt_f has been explicitly defined using function<> while addInt_l is a lambda whose type is type-inferenced with auto.
When I compiled the code, the flip function can accept the explicitly type-defined version of addInt but not the lambda version, giving an error saying that,
testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
The next few lines show that the lambda version (as well as a 'raw' version) can be accepted if it's explicitly cast to the appropriate function<> type.
So my questions are:
Why is it that a lambda function does not have a function<> type in the first place? In the small example, why does not addInt_l have function<int (int,int)> as the type instead of having a different, lambda type? From the perspective of functional programming, what's the difference between a function/functional object and a lambda?
If there is a fundamental reason that these two have to be different. I heard that lambda's can be converted to function<> but they are different. Is this a design issue/defect of C++11, an implementation issue or is there a benefit in distinguishing the two as the way it is? It seems that the type-signature of addInt_l alone has provided enough information about the parameter and return types of the function.
Is there a way to write the lambda so that the above mentioned explicit type-casting can be avoided?
Thanks in advance.
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}
std::function is a tool useful to store any kind of callable object regardless of its type. In order to do this it needs to employ some type erasure technique, and that involves some overhead.
Any callable can be implicitly converted to a std::function, and that's why it usually works seamlessly.
I'll repeat to make sure it becomes clear: std::function is not something just for lambdas or function pointers: it's for any kind of callable. That includes things like struct some_callable { void operator()() {} };, for example. That is a simple one, but it could be something like this instead:
struct some_polymorphic_callable {
template <typename T>
void operator()(T);
};
A lambda is just yet another callable object, similar to instances of the some_callable object above. It can be stored in a std::function because it's callable, but it doesn't have the type erasure overhead of std::function.
And the committee plans to make lambdas polymorphic in the future, i.e., lambdas that look like some_polymorphic_callable above. Which std::function type would such a lambda be?
Now... Template parameter deduction, or implicit conversions. Pick one. That's a rule of C++ templates.
To pass a lambda as a std::function argument, it needs to be implicitly converted. Taking a std::function argument means that you're choosing implicit conversions over type deduction. But your function template needs the signature to be deduced or provided explicitly.
The solution? Don't restrict your callers to std::function. Accept any kind of callable.
template <typename Fun>
auto flip(Fun&& f) -> decltype(std::bind(std::forward<Fun>(f),_2,_1))
{ return std::bind(std::forward<Fun>(f),_2,_1); }
You may now be thinking why do we need std::function then. std::function provides type erasure for callables with a known signature. That essentially makes it useful to store type-erased callables and to write virtual interfaces.
Because function<> employs type erasure. This allows several different function-like types to be stored in a function<>, but incurs a small runtime penalty. Type erasure hides the actual type (your specific lambda) behind a virtual function interface.
There is a benefit to this: one of the C++ design "axioms" is to never add overhead unless it is really needed. Using this setup, you do not have any overhead when using type inference (use auto or pass as a template parameter), but you still have all the flexibility to interface with non-template code through function<>. Also note that function<> is not a language construct, but a component of the standard library that can be implemented using simple language features.
No, but you can write the function to just take the type of the function (language construct) instead of the specifics of the function<> (library construct). Of course, that makes it a lot harder to actually write down the return type, since it does not directly give you the parameter types. However, using some meta-programming a la Boost.FunctionTypes you can deduce these from the function you pass in. There are some cases where this is not possible though, for example with functors that have a templated operator().
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.
int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
Can lambdas replace all uses of std::bind?
Is std::bind as optimal as implementing it as a lambda instead?
What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
I wouldn't describe the operator() of std::function as 'generated' (it's a regular member), but otherwise that is a good description. Optimizations are up to your compiler, but be warned that to optimize the indirection of std::function (which requires the use of type erasure) a compiler may need to perform heroics.
Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
The call to std::bind returns a functor of unspecified type, and a copy of that functor is stored inside the x object. This copy will live as long as x itself. There is no name involved so I'm not sure what you mean by that.
Can lambdas replace all uses of std::bind?
No. Consider auto bound = std::bind(functor, _1); where functor is a type with an overloaded operator(), let's say on long and int. Then bound(0L) doesn't have the same effect as bound(0) and you can't replicate that with a lambda.
Is std::bind as optimal as implementing it as a lambda instead?
This is up to the compiler. Measure yourself.
What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
It's a function type. Perhaps you're already familiar with the syntax for pointers/references to functions: void(*)(), int(&)(double). Then just remove the pointer/reference out of the type, and you just have a function type: void(), int(double). You can use those like so:
typedef int* function_type(long);
function_type* p; // pointer to function
1 . Does x(123) actually call the operator() of the functor which std::function generated which in turn calls the operator() of the functor which std::bind generated which finally calls func? Does this get optimized into something as optimal as calling func(123)?
If you have optimizations enabled, the 'stuff' gets inlined and you can count on this being as optimal as calling func(123).
2 . Where does the functor live which std::bind generates? In what scope? And how does std::bind name it? (can there be name collisions)
Precising: bind generates a 'fleeting', implementation defined, bind expression, that is assignable to function<>. Function is just a class template (Thanks, Luc T.). And it lives in the standard library. However, the bind expressions are implementation defined.
The standard library does come with traits (std::is_bind_expression<>) to allow MPL detection of such expressions. One decisive feature of bind expressions over std::function is that they are (what I'd call) deferred callable objects (i.e. that they retain full call site semantics including the ability to select overloads at the actual application site). std::function<>, on the other hand, commits to a single prototype and internally stores the callable object by type erasure (think variant or any).
3 . Can lambdas replace all uses of std::bind?
4 . Is std::bind as optimal as implementing it as a lambda instead?
AFAICT lambdas should compile down to about the same as the bind expressions. One thing that I think lambdas can't do that bind expressions can is nested bind expressions
Edit While the specific idiom of nested bind expressions is not replicatable using lambdas, lambdas are of course able to express (nearly) the same much more naturally:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5 . What's up with the syntax of the template argument of std::function? How does that get parsed and how can I use that template argument syntax elsewhere?
It is just a function signature (the type of a function), being passed as template parameter.
You can also use it as a function parameter type, which degrades to a function pointer(similar to how array by-value parameters degrade to pointers, Thanks David!).
In practice, most anywhere, as long as you don't have a need to name a variable/type:
void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax
void sample(int, double) { }
int main()
{
receiveFunction(sample);
}
void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
// void ( f)(int, double) // ... also ok
{
// ..
}
Can lambdas replace all uses of std::bind?
C++14 will allow lambdas to mostly replace bind. Responding in particular to Luc Danton's answer, in C++14, you can write templated lambdas using auto such that bound(0) and bound(0L) behave differently.