【发布时间】:2019-04-12 20:51:50
【问题描述】:
我正在尝试从可变参数模板创建参数并将其转发到存储函数。如果参数是(typename... Args),我想迭代每种类型并从存储容器中获取该类型的参数,然后将参数转发给函数。
我尝试了不同的方法,但最后总是无法存储无类型的参数向量,也无法将向量作为单独的参数转发。
这是我想要完成的一些伪代码。
template <typename S, typename... Args>
void store_lambda() {
vec.push_back([this]() -> void {
ArgumentList arguments;
(get_arguments<Args>(arguments), ...);
my_function(arguments...);
});
}
template <typename T>
void get_arguments(ArgumentList& arguments) {
arguments.append(inner_storage.get<T>();)
}
void my_function(SomeStruct& s, const AnotherStruct& as) {
// do something with arguments
}
ArgumentList 类型没有实现(并且可能无法实现),但这是我正在尝试创建的系统。
编辑:更多解释
这是我的系统的外观:
struct WorkerWrapperBase {
public:
virtual ~WorkerWrapperBase() {}
}
template <typename... Args>
using exec_fn = std::function<void()>;
template <typename Job>
using job_ptr = std::unique_ptr<Job>;
template <typename J, typename R = void, typename... Args>
struct WorkerWrapper {
exec_fn<Args...> fn;
job_ptr<J> job_ptr;
WorkerWrapper(J* job, R (S::*f)(Args...) const)
: job_ptr{job_ptr<J>(job)} {
fn = [this, f]() -> R {
(job_ptr.get()->*f)(/* send arguments fetched from Args as explained above */);
};
}
};
struct CollectionOfWorkers {
std::vector<WorkerWrapperBase> workers;
template <typename Worker>
void add() {
workers.push_back(WorkerWrapper(new Worker(), &Worker::execute));
}
}
用法如下所示:
struct TestWorker {
void execute(SomeStruct& s, const AnotherStruct& as) const {
// do something with arguments
}
}
CollectionOfWorkers.add<TestWorker>();
// and then somewhere we can loop each Worker and call their execute function
我想创建一个干净的 API,您可以在其中创建一个具有包含执行函数的简单结构的 Worker。然后,参数的类型将用于尝试获取存储在容器中的每种类型的实例的引用。然后将其发送到执行函数。这个想法来自Game Engine talk
【问题讨论】:
-
您在寻找
std::tuple和std::apply()吗? -
解决这个问题需要了解两件事:1)参数最初来自哪里,2)那个函数来自哪里?您能否提供一个示例用法/解释您尝试将其用于什么任务?
-
我做了很多与你想做的非常相似的事情;我只是不太清楚你要做什么
-
@JorgePerez 添加了更多解释
-
你看过std::tuple吗?您还可以使用 std::function 进行类型擦除。
标签: c++ metaprogramming c++17 variadic-templates template-meta-programming