26

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?

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
Julio Guerra
  • 5,523
  • 9
  • 51
  • 75

2 Answers2

25

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));
rhashimoto
  • 15,650
  • 2
  • 52
  • 80
2

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.

phogbin
  • 21
  • 1
  • In such a simple case, a lambda is readable and does work. But if the function has parameters and/or return value, it becomes more verbose. – HolyBlackCat Oct 13 '19 at 21:01