我想保存模板参数列表并将其传递给函数。
像std::thread
一样,将参数传递给线程。参数类型是模板化的,参数计数不是静态的。
示例,它将如何工作:
class CallbackList {
public:
Callback(/* Type of list of template args */ args) {
this->saved_args = args;
}
void Call() {
this->callback(saved_args);
}
private:
/* Type of list of template args */ saved_args;
CallbackType callback;
}
或者我该如何实现:
template<typename ...Args>
class CallbackList {
public:
using CallbackPrototype = /* some prototype */;
void RegisterCallback(CallbackPrototype callback, Args... args) {
CallbackInfo callback_info;
callback_info.callback = callback;
callback_info.args = { args... };
this->callbacks.push_back(callback_info);
}
void Call() {
for (CallbackInfo& callback_info : this->callbacks)
callback_info.callback(callback_info.args);
}
private:
struct CallbackInfo {
CallbackPrototype callback;
/* what type should be here? tuple? args count are not static */ args;
};
std::vector<CallbackInfo> callbacks;
}
有可能吗?
我该如何实施?
答案 0 :(得分:4)
如果您不希望回调依赖于参数的类型,则必须使用某种类型的擦除。例如,您可以使用std::function
中的<functional>
:
#include <functional>
#include <iostream>
class Lazy_Callback
{
public:
template <typename F, typename ...Args>
Lazy_Callback(F && f, Args && ...args)
: _fun([=]() { return f(args...); })
{ }
void call() const
{
_fun();
}
protected:
private:
std::function<void()> _fun;
};
void print_int(int x)
{
std::cout << "x = " << x << "\n";
}
int main()
{
Lazy_Callback lc(print_int, 5);
lc.call();
}
如果可以将回调模板化,则可以使用std::tuple
存储参数:
#include <tuple>
#include <iostream>
template <typename F, typename ...Args>
class Lazy_Callback
{
public:
template <typename ...Ts>
Lazy_Callback(F f, Ts && ...ts)
: _f(f), _args(ts...)
{ }
void call() const
{
return std::apply(_f, _args);
}
protected:
private:
F _f;
std::tuple<Args...> _args;
};
template <typename F, typename ...Ts>
Lazy_Callback<F, std::decay_t<Ts>...> make_callback(F && f, Ts && ...ts)
{
return { std::forward<F>(f), std::forward<Ts>(ts)... };
}
void print_int(int x)
{
std::cout << "x = " << x << "\n";
}
int main()
{
auto lc = make_callback(print_int, 5);
lc.call();
}
答案 1 :(得分:0)
您是否正在寻找类似std::bind
的东西?这是一个简单的示例,您可能会扩展:
#include <iostream>
#include <functional>
template <typename T1, typename T2>
void printSum(const T1& a, const T2& b)
{
std::cout << a + b << std::endl;
}
int main()
{
const auto callback = std::bind(&printSum<int, int>, 1, 2);
// ...
callback();
}