Dav*_*one 10 c++ templates template-specialization c++11 universal-reference
如何专门化一个采用通用参考参数的函数模板?
foo.hpp:
template<typename T>
void foo(T && t) // universal reference parameter
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中
template<>
void foo<Class>(Class && class) {
// do something complicated
}
Run Code Online (Sandbox Code Playgroud)
在这里,Class不再是推断类型,因此是Class完全; 它不可能是Class &,所以参考折叠规则对我没有帮助.我或许可以创建另一个带Class &参数的特化(我不确定),但这意味着foo为所有参数的rvalue/lvalue引用的每个可能组合复制所包含的所有代码,这是通用引用应该避免的.
有没有办法实现这个目标?
如果有更好的解决方法,请更具体地说明我的问题:
我有一个可以连接到多个游戏服务器的程序,并且每个服务器在大多数情况下都使用相同的名称调用所有内容.但是,对于一些事情,它们的版本略有不同.这些东西可以有几个不同的类别:移动,项目等.我写了一个通用的"移动字符串移动枚举"内部代码调用的函数集,我的服务器接口代码有类似的功能.但是,有些服务器有自己的内部ID,它们与之通信,有些使用字符串,有些则在不同情况下使用.
现在我想做的是让它更通用一点.
我希望能够打电话ServerNamespace::server_cast<Destination>(source).这将允许我从a转换Move为a std::string或ServerMoveID.在内部,我可能需要制作副本(或从中移动),因为某些服务器要求我保留已发送消息的历史记录.通用引用似乎是解决这个问题的明显方法.
我现在想到的头文件只会暴露出来:
namespace ServerNamespace {
template<typename Destination, typename Source>
Destination server_cast(Source && source);
}
Run Code Online (Sandbox Code Playgroud)
并且实现文件将所有合法转换定义为模板特化.
我认为最好的解决方案是使用标签调度系统,在标签上重载而不是实际类型:
struct foo {
struct tag {};
};
struct bar {
struct tag {};
};
template<typename Destination, typename Source>
Destination server_cast(Source && source, foo::tag) {
// foo
}
template<typename Destination, typename Source>
Destination server_cast(Source && source, bar::tag) {
// bar
}
template<typename Destination, typename Source>
Destination server_cast(Source && source) {
return server_cast<Destination>(std::forward<Source>(source), typename std::remove_reference<Source>::type::tag());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
918 次 |
| 最近记录: |