我想尽可能地尝试用这个问题来表达这个问题,但它确实与我编程的游戏有关。
我有一个有std :: map成员的类:
class Player {
...
private:
std::map<Action, Command> mActionBinding;
...
}
Action是Player类中的枚举。它包含ActionLeft,例如MoveLeft或MoveRight。 Command是一个包含函数和类别的结构。
struct Command
{
Command();
std::function<void(SceneNode&, sf::Time)> action;
unsigned int category;
// SceneNode& node
};
这个系统背后的想法是我可以将一个将操作SceneNode(我游戏中的可绘制对象)的函数绑定到一个SceneNode类别。游戏的update()将迭代我游戏中的所有SceneNodes,并在SceneNode上执行命令,如果该SceneNode的类别与命令中的类别匹配。 (如果这听起来很熟悉,这是SFML的GQE引擎,源代码可以在这里找到:https://github.com/LaurentGomila/SFML-Game-Development-Book)
我希望命令比此实现更具体。我希望在SceneNode上执行命令,如果该SceneNode与命令指定的那个匹配,而不仅仅是类别比较。
但是,命令是在此Player类中创建的,它们是在该std :: map中创建的。 Player的构造函数调用initializeAction()函数,该函数调用类似:
mActionBinding[MoveLeft].action =
derivedAction<SpaceCraft>(SpaceCraftMover(-playerSpeed, 0.f));
基本上,它将动作设置为操纵航天器节点的某个功能。稍后在Player构造函数中,mActionBinding的命令类别设置如下:
for(auto& pair : mActionBinding)
pair.second.category = Category::PlayerSpaceCraft;
我的问题:Command的构造函数在我能看到的地方被调用了no。我想更改Command的构造函数以接受SceneNode&amp;所以我可以将它设置为SpaceCraft节点(用注释的SceneNode&amp;替换unsigned int)。如何以可以看到Command(SceneNode&amp;)的方式创建这些命令,从而能够正确设置它?换句话说,我怎么能得到这个:
Command::Command(SceneNode& n)
: action()
// , category(Category::None)
, node(n)
{}
目前在stl_map.h中给出了一个我不明白的错误,可能是因为在Player的函数中错误地调用了Command构造函数
提前致谢,对这个冗长的问题感到抱歉,但我认为上下文是必要的。
答案 0 :(得分:2)
如果我正确理解了这个问题,我认为你正在观察std::map::operator[]
的创建 - 如果不存在并返回 - 引用行为:
如果[key]与容器中任何元素的键不匹配,该函数将使用该键插入一个新元素,并返回对其映射值的引用。请注意,即使没有为元素指定映射值(使用其默认构造函数构造元素),这也总是会将容器大小增加1。
如果您想自己构建Command
对象(可能是通过非default constructor),您可能需要调用std::map::insert
或std::map::emplace
,具体取决于语义你想要(以及你的编译器对更新标准的支持),而不是使用operator[]
。
将这些全部拉到一起,尝试这样的事情:
Command cmd(theSceneNode);
cmd.action = derivedAction<SpaceCraft>(SpaceCraftMover(-playerSpeed, 0.f));
// more command setup, possibly
mActionBinding.insert(std::make_pair(MoveLeft, cmd));
// or possibly, mActionBinding.insert(std::make_pair(MoveLeft, std::move(cmd)));