我试图声明一个指向模板化类成员的std ::函数时出现以下错误。
错误C2672'
std::invoke
':找不到匹配的重载功能
template <typename InputArchive, typename OutputArchive, typename ... Components>
class LevelSerializer {
...
template <typename Component>
void initRegistry() {
...
std::function<void(entityx::Entity, OutputArchive)> f(std::bind(&LevelSerializer<InputArchive, OutputArchive, Components...>::saveComponent<Component>, this)); // errors
}
...
// I'm trying to point to an instance of this function
template <typename T>
void saveComponent(entityx::Entity& entity, OutputArchive& archive)
};
entityx::Entity
是固定(非模板)类型。为什么这样做会失败?
答案 0 :(得分:4)
你有两个问题:首先,你的行:
std::function<void(entityx::Entity, OutputArchive)>
f(std::bind(&LevelSerializer<InputArchive, OutputArchive, Components...>::saveComponent<Component>, this)); // errors
应该是
typedef std::function<void(entityx::Entity, OutputArchive) functype;
typedef LevelSerializer<InputArchive, OutputArchive, Components...> LS;
functype f(std::bind(&LS::saveComponent<Component>, this,
std::placeholders::_1, std::placeholders::_2 ));
你的问题是,当你编写它时,你对std :: bind的调用试图返回一个没有参数的函数(并且它最终没有足够的参数用于你试图调用的成员函数)。你需要绑定占位符参数,以便a)成员函数有足够的参数; b)结果是有两个参数的东西。
暂且不说:在LevelSerializer模板中,裸LevelSerializer
引用带有参数的模板。实际上,你只需要:
typedef std::function<void(entityx::Entity, OutputArchive) functype;
functype f(std::bind(&LevelSerializer::saveComponent<Component>, this,
std::placeholders::_1, std::placeholders::_2 ));
你的第二个问题是签名不匹配(感谢Piotr Skotnicki)。 function
的模板参数是一个函数,它按值接收两个参数。您的成员函数通过非const引用获取两个参数。您需要至少将模板参数更改为:
typedef std::function<void(entityx::Entity&, OutputArchive&) functype;
functype f(std::bind(&LevelSerializer::saveComponent<Component>, this,
std::placeholders::_1, std::placeholders::_2 ));
...但您可能希望将entity
参数更改为const引用。
答案 1 :(得分:2)
Martin Bonner更直接地解决了这个问题,但我想我注意到在我的情况下,我收到了以下代码的错误:
std::bind(&ClassName::FuncName, objName, _1);
并修复它:
std::bind(&ClassName::FuncName, objName, std::placeholders::_1);
显然我的一个标题包含一个带占位符的boost库,_1指的是boost版本而不是我的版本。