Вот набор Variadic
Template
Classes
, который позволит вам легко это сделать, если у вас есть C++17
.Первый класс просто хранит универсальную версию std::function
любого типа!Второй класс хранит первый класс через member function
и будет register
либо function pointer
, function object
или lambda
.У этого также есть другой member function
, который будет invoke
это.В настоящее время я использую lambdas
в этом примере.У меня есть два lambdas
, 1 st берет два типа int
, добавляет их и возвращает int
, как в вашей проблеме выше.2 nd принимает два std::strings
объединения их, затем выводит их на экран, но не возвращает никакого значения.Вы даже можете расширить это, сохранив std::vector<Functor<>>
в классе драйверов.register_callback
изменится незначительно, чтобы вставить их в вектор, а call_back
у вас есть варианты.Вы можете либо вызвать их все за один раз, либо выполнить поиск по значению индекса, чтобы вызвать конкретное, но я оставлю это в качестве упражнения для вас.
#include <string>
#include <iostream>
#include <functional>
template<typename RES_TYPE, typename... ARG_TYPES>
struct Functor {
std::function<RES_TYPE( ARG_TYPES... )> func_;
};
template<typename RES_TYPE, typename... ARG_TYPES>
class Driver {
private:
Functor<RES_TYPE, ARG_TYPES...> functor;
public:
Driver() = default;
~Driver() = default;
void register_callback( const Functor<RES_TYPE, ARG_TYPES...> &func ) {
functor = func;
}
RES_TYPE call_back( ARG_TYPES... args ) {
return functor.func_( std::forward<ARG_TYPES>(args)... );
}
};
int main() {
// Function Type: int ( int, int );
Functor<int, int, int> func;
auto lambda = []( int a, int b ) { return a + b; };
func.func_ = lambda;
Driver<int, int, int> driver;
driver.register_callback( func );
int a = 3;
int b = 5;
std::cout << driver.call_back( a, b ) << '\n';
std::cout << driver.call_back( 7, 5 ) << '\n';
// Function Type: void ( string, string );
Functor<void, std::string, std::string> func2;
auto lambda2 = []( std::string str1, std::string str2 ) {
str1 = str1 + " " + str2;
std::cout << str1 << '\n';
};
Driver <void, std::string, std::string> driver2;
func2.func_ = lambda2;
driver2.register_callback( func2 );
std::string str1 = "Hello";
std::string str2 = "World";
driver2.call_back( str1, str2 );
driver2.call_back( "Generic", "Programming" );
return 0;
}
Вывод:
8
12
Hello World
Generic Programming
Если вы заметили этот код здесь;нет необходимости связываться с указателями или динамической памятью.Об этом все заботятся, используя для нас std::function
и классы по умолчанию dtors
.
Я старался изо всех сил создать его с простотой, удобочитаемостью, делая его портативным и универсальным, насколько это возможно.,Я уверен, что могут быть сделаны некоторые улучшения, но я думаю, что это соответствует тому, что вы просите.