Быстрые делегаты C++ - Функторы (функции-объекты)

ОГЛАВЛЕНИЕ

Функторы (функции-объекты) 

Ftor2 f2("f2");

// создание копии

bool dummy = true;
fd::delegate1 < void, int > dg1(f2, dummy);
// сохраняем внутри клонированный функтор

fd::delegate1 < void, int > dg2(&f2, dummy);
// сохраняем только указатель на функтор


dg1(123);  // (внутренняя копия f2).operator ()(123);

dg2(234);  // (&f2)->operator ()(234);


// присваивание ( специальный оператор <<= )

fd::delegate1 < void, int > dg3, dg4, dg5, dg6;
dg3 <<= f2;       // сохраняем внутри клонированный функтор

dg4 <<= &f2;      // сохраняем только указатель на функтор

dg5 <<= Ftor1();  // сохраняем внутри клонированный функтор

dg6 <<= &Ftor1(); // сохраняем только указатель на временный функтор

dg3(345);  // (внутренняя копия f2).operator ()(345);

dg4(456);  // (&f2)->operator () (456);

dg5(567);  // (внутренняя копия временного Ftor1).operator ()(567);

dg6(678);  // (&временный Ftor1, который уже
           // был разрушен)->operator ()(678); Ошибка времени исполнения!

Сначала мы не рассматривали включение поддержки функторов. Когда мы изменили план (после завершения копирования кода для соглашения о вызовах), мы пытались реализовать нормальный оператор присваивания (operator =) для функтора, но это вызвало слишком много проблем с неоднозначностью перегруженных функций. Мы почти отказались от этого и планировали заставить пользователя реализовать это, например, так:

Ftor1 f1;
fd::delegate2 < void, Ftor1 *, int > dg1(&Ftor1::operator ());
dg1(&f1, 123);

Мы думали, что вам понравится operator <<= вместо вышеприведенного.

Делегат не может быть делегатом без чего-то такого, что он представляет. То есть обернутая целевая вызываемая сущность должна быть в достоверном состоянии, когда вызывается делегат. Это поведение несколько отличается от того, как boost::function присваивается функтору. По умолчанию boost::functionboost::ref or boost::crefВ предыдущей версии наш делегат только сохранял ссылку (указатель) на присваиваемый целевой функтор. Если это сохраняющий текущее состояние функтор, то вызывающий отвечает за то, чтобы сохранять целевой функтор незатронутым при вызове (точно такая же идея применяется к вызываемому объекту, позже связываемому с функцией-членом). внутри клонирует целевой функтор (выделение памяти кучи), если в противном случае не используется явно.

Но в новой версии добавлена функция клонирования связанного объекта, поэтому синтаксис operator <<=bool (логический) как второй аргумент для функтора. был изменен, чтобы отличить сохраненную версию и клонированную версию ссылки (указателя). Также выше приведен специальный конструктор копии, который принимает формальный параметр