c++ - 专门化采用通用引用参数的函数模板

标签 c++ templates c++11 template-specialization universal-reference

如何特化采用通用引用参数的函数模板?

foo.hpp:

template<typename T>
void foo(T && t)    // universal reference parameter

foo.cpp

template<>
void foo<Class>(Class && class) {
    // do something complicated
}

在这里,Class不再是推导类型,因此是 Class确切地;它不可能是Class & ,所以引用折叠规则在这里对我没有帮助。我也许可以创建另一个需要 Class & 的特化参数(我不确定),但这意味着复制 foo 中包含的所有代码对于所有参数的右值/左值引用的每种可能组合,这是通用引用应该避免的。

有什么办法可以做到这一点吗?

如果有更好的解决方法,请更具体地说明我的问题:

我有一个程序可以连接到多个游戏服务器,每个服务器在大多数情况下都用相同的名称调用所有内容。但是,它们在某些方面的版本略有不同。这些东西可以分为几个不同的类别:一个移动,一个项目等。我已经编写了一种通用的“移动字符串以移动枚举”函数集供内部代码调用,我的服务器接口(interface)代码具有类似的功能。然而,有些服务器有自己的内部 ID,它们可以与之通信,有些使用字符串,有些在不同情况下同时使用这两种 ID。

现在我要做的是让它更通用一些。

我希望能够调用类似 ServerNamespace::server_cast<Destination>(source) 的东西.这将允许我从 Move 转换到 std::stringServerMoveID .在内部,我可能需要制作拷贝(或从中移动),因为某些服务器要求我保留发送消息的历史记录。通用引用似乎是解决这个问题的明显方法。

我现在想到的头文件会简单地暴露这个:

namespace ServerNamespace {

template<typename Destination, typename Source>
Destination server_cast(Source && source);

}

并且实现文件会将所有合法转换定义为模板特化。

最佳答案

我认为最好的解决方案是使用标签分发系统,在该系统中重载标签而不是实际类型:

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());
}

关于c++ - 专门化采用通用引用参数的函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13654099/

相关文章:

c# - __declspec(dllexport)::vector <std::string>

c++ - 无法调用构造函数(模板-模板参数)

java - 单作者多读者原语图

c++ - 函数模板重载和歧义

c++ - 为什么我的 Qt Widget 没有显示?

c++ - C 无符号 64 位整数的种群计数,最大值为 15

c++ - 在模板函数中声明依赖于未知类型的变量

c++ - 这段代码发生了什么?

c++ - 初始化常量变量并在失败时断言 (c++)

c++ - 模板化赋值运算符和自检