提问人:Thomas 提问时间:10/17/2023 最后编辑:Thomas 更新时间:10/17/2023 访问量:59
使用模板参数创建传递给另一个函数的参数列表
Using template parameters to create a list of arguments which are passed to another function
问:
我正在创建一个系统,用户可以通过定义数据片段(称为资源)和作用于资源的函数(称为系统)来创建应用程序。我希望用户纯粹提供某种类型的函数指针,并且从该类型中我想推断出需要传递给该函数的资源。
下面是一些上下文代码:
#include <vector>
#include <unordered_map>
#include <memory>
using TypeID = size_t;
class Type
{
public:
template <class T>
static TypeID ID()
{
static TypeID id = s_Counter++;
return id;
}
private:
inline static TypeID s_Counter = 0;
};
struct Resource
{
virtual ~Resource() = default;
};
template <typename T>
struct Res : public Resource
{
inline static const TypeID ID = Type::ID<T>(); // Type::ID<T>() just returns a unique ID for every type
T Data;
};
class Application
{
private:
std::unordered_map<TypeID, std::unique_ptr<Resource>> m_Resources;
std::vector<void(*)()> m_Systems;
public:
template <typename T>
void AddResource()
{
m_Resources[Res<T>::ID] = std::make_unique<Res<T>>();
}
template <typename T>
T& GetResource()
{
return m_Resources[Res<T>::ID]->Data;
}
template <typename... Resources>
void AddSystem(void (*pSystem)(Resources...))
{
m_Systems.push_back([pSystem]() {
pSystem(/*Here, for every parameter in the parameter pack Resources,
I want to call GetResource<>() with the appropriate template parameter*/);
});
}
};
struct Foo
{
int a;
float b;
};
void system(Foo foo, int num, float val)
{
/*do stuff with foo, num and val*/
}
int main()
{
Application app;
app.AddResource<Foo>();
app.AddResource<int>();
app.AddResource<float>();
app.AddSystem(system);
}
在函数中,我想将模板参数列表(例如)转换为函数调用列表,以便将这些函数的返回值传递到用户定义的函数中。此示例应生成该行。AddSystem
<int, float, Foo>
GetResource<int>(), GetResource<float>(), GetResource<Foo>()
pSystem
pSystem(GetResource<int>(), GetResource<float>(), GetResource<Foo>());
有没有一种便携式方法可以做到这一点?比如标准库提供的功能?
如果有另一种明显的方法可以达到相同的结果,也请告诉我,这个设计还没有一成不变。
答:
1赞
463035818_is_not_an_ai
10/17/2023
#1
若要传递到函数指针,可以使用包扩展:Get<Args>...
#include <iostream>
#include <utility>
void foo(int a,float b,double c) {
std::cout << a << b << c;
}
template <typename T> int get() { return 0; }
template <typename ...Args>
void bar(void(*f)(Args...)) {
f( get<Args>()...); // calls f(get<int>(),get<float>(),get<double>())
}
int main() {
bar(foo);
}
评论
0赞
Thomas
10/17/2023
不知道包扩展可以以这种方式工作。谢谢!
上一个:如何展开此 C++ 模板参数包
下一个:取决于类模板参数的条件变量类型
评论
m_Systems
m_Resources
Type::ID<Data>
然后就没有意义了。您可以在此处看到更多代码错误 godbolt.org/z/a4jE351de。T Data