Обратные вызовы в C++ | страница 48
>//General specialization
>template
>class function;
>//Partial specialization
>template
>class function
>{
>public:
> Return operator()(ArgumentList… arguments) // (3)
> {
> }
>};
В строке 1 объявлена общая специализация шаблона. Реализация класса здесь отсутствует, поскольку для каждой сигнатуры она будет различной. В строке 2 объявлен шаблон для частичной специализации, в котором два аргумента: тип возвращаемого значения и пакет параметров, передаваемых функции вызова.
В строке 3 объявлен перегруженный оператор, выступающий в качестве функции вызова. Сигнатура оператора содержит тип возвращаемого значения Return и пакет входных параметров arguments, которые разворачиваются в список аргументов. Таким образом, в зависимости от пакета и возвращаемого значения будет сгенерирована соответствующая специализация шаблона.
Описанная реализация всего лишь демонстрирует настройку сигнатуры. Практической пользы от нее немного, потому что тело перегруженного оператора пустое, и вызов осуществлен не будет. Используя описанную технику, добавим настройку сигнатуры к аргументу, реализующему стирание типов (Листинг 48).
>template
>class UniArgument;
>template
>class UniArgument
>{
>private:
> struct Callable
> {
> virtual Return operator()(ArgumentList… arguments) = 0; // (3)
> };
> std::unique_ptr
> template
> struct CallableObject : Callable
> {
> Argument storedArgument;
> CallableObject(Argument argument) : storedArgument(argument) { }
> Return operator() (ArgumentList… arguments) override // (8)
> {
> //return storedArgument(arguments…);
> return std::invoke(storedArgument, arguments…); // (9)
> }
> };
>public:
> Return operator() (ArgumentList… arguments) // (10)
> {
> return callablePointer->operator()(arguments…); // (11)
> }
> template
> void operator = (Argument argument)
> {
> callablePointer.reset(new CallableObject
> }
>};
По сравнению с реализацией для фиксированной сигнатуры (Листинг 45 п. 4.5.1) изменения здесь следующие. Класс аргумента (строка 1) объявляется в виде шаблона. Параметрами шаблона выступают Return – тип значения, возвращаемого функцией, и ArgumentList