我正在创建一个系统,用户可以通过定义数据(称为资源)和作用于资源的函数(称为系统)来创建应用程序。我希望用户纯粹提供一个特定类型的函数指针,并从该类型推断出需要传递给该函数的资源。
下面是一些上下文代码:
#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条答案
按热度按时间zbwhf8kr1#
要将
Get<Args>...
传递给函数指针,可以使用包扩展: