C++ 将可变参数传递给模板函数时出现编译错误
我有以下模板方法:C++ 将可变参数传递给模板函数时出现编译错误,c++,c++11,templates,bind,variadic-templates,C++,C++11,Templates,Bind,Variadic Templates,我有以下模板方法: 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<A
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;
});
}
像这样调用代码时:
manager.register_scene<SceneWithArgs>("test", "arg");
manager.register_场景(“测试”、“参数”);
我真的不明白这个错误,也不知道如何修复它
我最初通过在lambda内部调用create解决了这个问题,这在GCC 4.9及以上版本中有效,但我必须与GCC 4.8.4兼容,并且存在一个错误,它阻止在lambda内部使用可变参数:(
更新
好的,因此添加std::decay(如注释中所示)并不能完全解决问题,第一个参数一直在推导Window*&&
,而不是Window*
,但实际上指定了func
的类型(例如std::function
),而不是使用auto
,从而使事情得以编译
我不知道为什么…您没有显示
create
的声明,但我假设它如下所示:
template <typename... Args>
static SceneBasePtr create(Args&&...);
请注意,引用折叠规则将第一个参数转换为r值引用,而其余参数为l值引用
std::bind
也会推断类型。但是,std::bind
会希望存储参数,以便以后可以重用。问题是std::bind
无法存储const char[5]
。相反,它将衰减每个参数的类型。这意味着每个原始字符串文字将成为const char*
,并将作为此类型的l值参数传递给绑定函数,这与手动实例化的create
不匹配。窗口
参数也存在类似问题。它被推断为l值,但是,手动实例化的create
函数需要r值
最好不要明确指定函数模板的模板类型。如果由于某些原因(错误?)无法在lambda中使用args…
,则可以生成适当的创建
签名:
&T::template create<Window*&, typename std::decay<Args>::type&...>
// ~^~ ~~~~~~~~~^
您可能需要将
create
转换为create
&T::template create<Window*, Args&...>
template <typename T, typename... Args>
void register_scene(const std::string& name, Args&&... args);
//...
manager.register_scene<SceneWithArgs>("test", "arg");
static SceneBasePtr create(Window*&&, const char(&)[5], const char(&)[4]);
&T::template create<Window*&, typename std::decay<Args>::type&...>
// ~^~ ~~~~~~~~~^
static SceneBasePtr create(Window*&, const char*&, const char*&);