I'm getting the following error trying to declare an std::function pointing to a templated class member.
Error C2672 '
std::invoke
': no matching overloaded function found
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
is a fixed (non-template) type. Why does doing this fail?
You have two problems: Firstly, your line:
std::function<void(entityx::Entity, OutputArchive)>
f(std::bind(&LevelSerializer<InputArchive, OutputArchive, Components...>::saveComponent<Component>, this)); // errors
should be
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 ));
Your problem is that as you have written it, your call to std::bind is trying to return aa function with no arguments (and it ends up not having enough arguments for the member function you are trying to call). You need to bind in the place holder arguments so that a) the member function has enough arguments; b) the result is a thing that has two arguments.
As an aside: Inside the LevelSerializer template, a naked LevelSerializer
refers to the template with its arguments. So actually, you just need:
typedef std::function<void(entityx::Entity, OutputArchive) functype;
functype f(std::bind(&LevelSerializer::saveComponent<Component>, this,
std::placeholders::_1, std::placeholders::_2 ));
Your second problem is that the signatures don't match (thanks to Piotr Skotnicki for this). The template argument to function
is for a function that takes two parameters by value . Your member function takes two arguments by non-const reference . You need to change at least the template argument to:
typedef std::function<void(entityx::Entity&, OutputArchive&) functype;
functype f(std::bind(&LevelSerializer::saveComponent<Component>, this,
std::placeholders::_1, std::placeholders::_2 ));
... but you might want to change the entity
argument to be by const reference.
Martin Bonner addressed the question more directly, but I thought I'd note that in my case I received this error for the following code:
std::bind(&ClassName::FuncName, objName, _1);
And fixed it like so:
std::bind(&ClassName::FuncName, objName, std::placeholders::_1);
Apparently one of my headers included a boost library with placeholders, and _1 was pointing to the boost version instead of my version.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.