Basically, I would like to have the following semantic :
#include <functional> #include <iostream> class test { public: void add(std::function<void()> f) { f(); } void operator()() { ++x; } int x = 33; }; int main() { test t; t.add(t); // wanted: x == 34 instead: x == 33 since add(t) copies it }
I understand std::function wraps a copy of the callable object but is there any way to get a reference to a callable object using std::function?
You cannot pass a functor as a function pointer into a function that takes a function pointer, even if the functor has the same arguments and return value as the function pointer. Similarly, if a function expects a functor, you cannot pass in a function pointer.
Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions (via pointers thereto), lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
A function object, or functor, is any type that implements operator(). This operator is referred to as the call operator or sometimes the application operator. The C++ Standard Library uses function objects primarily as sorting criteria for containers and in algorithms.
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.
You want to use the std::ref
template function to create a reference wrapper for your instance:
std::reference_wrapper
is a class template that wraps a reference in a copyable, assignable object.Function templates
ref
andcref
are helper functions that generate an object of typestd::reference_wrapper
, using template argument deduction to determine the template argument of the result.
You would use it like this:
t.add(std::ref(t));
Another approach would be to pass in a lambda - binding t as a reference:
t.add( [&t]{ t(); } );
This seems more readable to me (but only because I'm familiar with lambdas and not std::bind). The distinction is perhaps reminiscent of an item in Scott Meyers' Effective Modern C++, #34: Prefer Lambdas to std::bind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With