定义std :: function指向函数模板实例的错误,该函数模板是模板化类的成员?

时间:2015-12-23 08:36:09

标签: c++ c++11

我试图声明一个指向模板化类成员的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是固定(非模板)类型。为什么这样做会失败?

2 个答案:

答案 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版本而不是我的版本。