Обратные вызовы в C++ | страница 49
– пакет параметров, определяющих типы передаваемых в функцию аргументов. При объявлении перегруженных операторов (строки 3, 8, 10), вместо конкретного типа возвращаемого значения подставляется параметр шаблона Return, вместо конкретных типов входных параметров подставляется ArgumentList. В местах, где происходит вызов оператора, пакет параметров раскрывается (строки 9 и 11), что означает, что вместо arguments будет подставлен список переменных с типами, заданными в пакете параметров.
Теперь в универсальном аргументе можно настраивать сигнатуру, как это продемонстрировано в Листинг 49.
>void ExternalHandler1(int eventID) {/*Do something*/} // (1)
>int ExternalHandler2(int eventID, int contextID) { return 0; } // (2)
>struct CallbackHandler // (3)
>{
> void operator() (int eventID) {}
> bool operator() (int eventID, int contextID) { return false; }
>};
>int main()
>{
> int capturedValue = 100;
> CallbackHandler callbackObject; // (4)
> UniArgument
> UniArgument
> argument1 = ExternalHandler1; // (7)
> argument2 = ExternalHandler2; // (8)
> argument1 = callbackObject; // (9)
> argument2 = callbackObject; // (10)
> argument1 = [capturedValue](int eventID) {/*Do something*/}; // (11)
> argument2 = [capturedValue](int eventID, int contextID) { /*DoSomething*/return 0; }; // (12)
> argument1(3); // (13)
> int res = argument2(4, 5); // (14)
> return res;
>}
В строках 1 и 2 объявлены две внешние функции с различными сигнатурами. В строке 3 объявлен функциональный объект, в котором перегружены операторы вызова функции с такими же сигнатурами. В строке 4 объявлен экземпляр указанного объекта.
В строках 5 и 6 объявлены универсальные аргументы, в которых с помощью параметров шаблона настраивается нужная сигнатура. Далее этим аргументам будут присваиваться различные объекты вызова в зависимости от заданной сигнатуры.
В строках 7 и 8 в аргумент передаются внешние функции. В строках 9 и 10 передается функциональный объект, у которого, в зависимости от настроенной сигнатуры будет вызван соответствующий перегруженный оператор. В строках 11 и 12 передаются лямбда-выражения. В строках 13 и 14 осуществляются вызовы в соответствии с заданной сигнатурой.
4.5.3. Вызов метода класса
В текущей реализации универсальный аргумент может работать с любыми объектами вызова, за исключением методов класса. Это связано с тем, что вызов метода класса имеет другой синтаксис, отличный от вызова функции. Как добавить поддержку вызова методов? Можно предложить следующее решение: при настройке объекта назначать указатель на метод, аналогично обычной функции, а при вызове передавать экземпляр класса как дополнительный аргумент.