我有以下模板方法:
template<typename T, typename... Args>
void register_scene(const std::string& name, Args&&... args) {
auto func = std::bind(&T::template create<Window*, Args&...>, std::placeholders::_1, std::forward<Args>(args)...);
_store_scene_factory(name, [=](Window* window) -> SceneBasePtr {
auto ret = func(window);
ret->set_name(name);
return ret;
});
}
基本上我需要做的就是将可变参数
Args
绑定到T::create
(它本身是一个静态的可变参数模板方法),但允许在调用时单独填充第一个参数(窗口)。以上代码会出现以下错误。
error: no match for call to ‘(const std::_Bind<std::shared_ptr<{anonymous}::SceneWithArgs> (*(std::_Placeholder<1>, const char*))(smlt::Window*&, const char (&)[4])>) (smlt::Window*&)’
auto ret = func(window);
~~~~^~~~~~~~
当以以下方式调用代码时:
manager.register_scene<SceneWithArgs>("test", "arg");
我并不真正理解这个错误,也不知道如何修复它。
起初我通过在lambda内部简单调用create来解决此问题,在GCC 4.9及以上版本上运行良好,但我必须保持与GCC 4.8.4的兼容性,并且存在一个bug,防止在lambda内使用可变参数:(
更新
好吧,添加std :: decay(如评论中所示)并没有完全解决问题,第一个参数仍然会推断为 Window *&&
而不是 Window *
,但实际上指定 func
类型(例如 std :: function< SceneBasePtr (Window *)>
)而不是使用auto
使事情编译。
但我不确定为什么...
create<Window*, Args&...>
改成create<Window*, typename std::decay<Args>::type&...>
。 - StoryTeller - Unslander Monica