Справочник по функторам через функцию std::

В принципе, я хотел бы иметь следующую семантику:

#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
}

Я понимаю, что std:: function обертывает копию вызываемого объекта, но есть ли способ получить ссылку на вызываемый объект с помощью std:: function?

Ответы

Ответ 1

Вы хотите использовать функцию шаблона std::ref, чтобы создать ссылочную оболочку для вашего экземпляра:

std::reference_wrapper - это шаблон класса, который обертывает ссылку в копируемый, назначаемый объект.

Шаблоны функций ref и cref являются вспомогательными функциями, которые генерируют объект типа std::reference_wrapper, используя аргумент шаблона вывод для определения аргумента шаблона результата.

Вы бы использовали его следующим образом:

t.add(std::ref(t));

Ответ 2

Другой подход заключается в передаче лямбда-связывания t в качестве ссылки:

t.add( [&t]{ t(); } );

Мне это кажется более читабельным (но только потому, что я знаком с лямбдами, а не с std::bind). Это различие, возможно, напоминает пункт в "Эффективном современном" Скотта Мейерса C++, № 34: Предпочитаю Lambdas std::bind.