Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functor reference through a std::function

Tags:

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?

like image 544
Julio Guerra Avatar asked Jun 20 '14 22:06

Julio Guerra


People also ask

How do you pass a functor as a 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.

Is std :: function copyable?

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.

What is a functor C++?

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.

Is std :: function a pointer?

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.


2 Answers

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 and cref are helper functions that generate an object of type std::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)); 
like image 62
rhashimoto Avatar answered Sep 23 '22 22:09

rhashimoto


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.

like image 41
phogbin Avatar answered Sep 22 '22 22:09

phogbin