C++ 如何处理这种情况(需要使用变量参数注册函数)

C++ 如何处理这种情况(需要使用变量参数注册函数),c++,variadic-functions,C++,Variadic Functions,我正在寻找关于如何处理这种情况的建议,因为迄今为止我所想到的一切都不起作用 我正在开发一款RPG游戏,目前正在开发图形系统。我的图形系统由一系列按特定顺序排列然后绘制的屏幕堆栈组成 屏幕堆栈基本上只是相关屏幕的集合,以及唯一的id和绘图顺序 i、 e 类屏幕堆栈 { //构造函数、getter/setter等。 私人: std::字符串StackName; 优先权; int-UID; 布尔有效; 布尔拉丝栈; bool-UpdateStack; 布尔输入; 布尔删除堆栈; std::vector

我正在寻找关于如何处理这种情况的建议,因为迄今为止我所想到的一切都不起作用

我正在开发一款RPG游戏,目前正在开发图形系统。我的图形系统由一系列按特定顺序排列然后绘制的屏幕堆栈组成

屏幕堆栈基本上只是相关屏幕的集合,以及唯一的id和绘图顺序

i、 e

类屏幕堆栈
{
//构造函数、getter/setter等。
私人:
std::字符串StackName;
优先权;
int-UID;
布尔有效;
布尔拉丝栈;
bool-UpdateStack;
布尔输入;
布尔删除堆栈;
std::vector OwnedScreens;//screen_ptr是围绕screen对象的共享_ptr
};
屏幕是一个简单的图形层,负责可视化游戏的某些部分,例如,有一个屏幕用于显示玩家清单、团队概述、团队在战斗中的状态、敌方等

我有一个屏幕管理器,负责存储创建屏幕堆栈的各种功能(即,创建战斗堆栈的功能将为玩家方、敌方、攻击动画屏幕、背景和用户界面创建一个屏幕)。每个屏幕堆栈创建函数都需要一组不同的参数来构造它。我现在做的是根据需要手动将堆栈创建函数添加到屏幕管理器中。例如,现在屏幕管理器有一个创建标题屏幕堆栈、开始菜单堆栈、战斗堆栈、超世界堆栈、tilemap堆栈等的功能

这是可行的,但很麻烦且杂乱无章。我想做的是,让屏幕管理器外部的文件能够向屏幕管理器注册堆栈创建函数,然后我可以只查找屏幕创建函数,而不必为我需要创建的每个堆栈向屏幕管理器添加新函数

我最初尝试添加一个
无序的
,StackCreationFunction的类型定义为

boost::function<ScreenStack (Engine& engine, ScreenManager& manager, const std::string screenName, const int StackID, const std::vector<std::string>& TryToCopyScreens, ...)> 
boost::函数
。。。是从cstdargs来的。其想法是,每个屏幕堆栈都会将自己的StackCreationFunction添加到此地图。但是,这不起作用,因为boost::函数对…无效

因此,本质上我试图做的是允许外部文件/屏幕能够向screenmanager注册它们自己的创建函数(具有可变参数),并且理想情况下能够在编译时/启动后立即注册。这感觉就像预处理器应该是可能的,但我不确定如何做到这一点。我被困在这里了,我真的希望有一个更好的解决方案,然后在屏幕管理器中添加许多堆栈创建者函数并将其弄乱

如果您有任何建议/更好的解决方案,我将不胜感激,如果以上内容不够清楚,我可以提供更多细节


谢谢

我不确定这是否回答了您的问题,但是如果您关心的是从类似解释器的代码调用不同签名的各种函数,那么您可以(至少在GNU/Linux下)使用(一个用于外部函数接口的库)为此。

我建议,与其让外部注册到系统中,不如考虑让系统调用外部实体。在这种情况下,系统将定位并加载一系列具有特定入口点的插件。您需要使用一些常规容器创建可变长度参数列表;数组或数据结构

每个屏幕堆栈创建函数都需要一组不同的参数来构造它

我认为这就是这里的问题所在,您需要在这里考虑一个抽象,以使您的地图正常工作。毕竟,调用代码实际上是如何提供这些额外参数的?当调用代码知道实例化了哪个类并可以提供参数时,就不需要映射。如果没有,映射就没有用处,因为您无法告诉堆栈创建函数提供哪些参数


最有可能的解决方案是boost::绑定掉StackCreator函数中通常会进入
..
参数的所有参数,并在无序映射中注册此绑定版本的函数,这可以从
..

中解放出来。您的问题非常清楚,但需要考虑的内容很多。如果你没有得到你想要的答案,我会建议你把你的问题去文本化,这样它会更短。也许添加一个设计模式和boost函数标签,以及将builder设计模式与工厂设计模式相结合就足够了吗?因此,所有屏幕堆栈都是默认可构造的,但是您有专门的构建器,其设置可以放在文件中进行查找,从而在返回对象之前构建对象。工厂可用于按名称获取所需的ScreenStack对象(可能还有供构建器使用的配置文件等)
boost::function<ScreenStack (Engine& engine, ScreenManager& manager, const std::string screenName, const int StackID, const std::vector<std::string>& TryToCopyScreens, ...)>