- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想为模板函数编写一个特化,它所特化的类型本身就是一个模板化类型。 (我使用的是 C++11 或更高版本。)
在下面的示例代码中,我有通用函数 convertTo
和 int
的工作特化, 允许我使用 convertTo<int>(s)
(如图所示)。但是我不知道如何为 std::set<T>
编写特化。 .这是我尝试过的:
#include <string>
#include <sstream>
#include <set>
#include <unordered_set>
using namespace std;
// generic version
template<class T> T convertTo(const char* str) {
T output;
stringstream ss(str, stringstream::in);
ss >> output;
return output;
}
// specialization for int. works.
template <>
int convertTo<int>(const char* str) {
return atoi(str);
}
template <>
template<class T> set<T> convertTo<set<T>>(const char* str) {
set<T> S;
// TODO split str by comma, convertTo<T>(each element) and put into S
return S;
}
template <>
template<class T> unordered_set<T> convertTo<unordered_set<T>>(const char* str) {
unordered_set<T> S;
// TODO split str by comma, convertTo<T>(each element) and put into S
return S;
}
int main() {
float f = convertTo<float>("3.141");
int i = convertTo<int>("123");
set<int> os = convertTo<set<int>>("9,8,7,6");
unordered_set<int> os = convertTo<unordered_set<int>>("9,8,7,6");
return 0;
}
使用 g++ 6.3.0 我收到错误消息:
too many template parameter lists in declaration of ‘std::set<T> convertTo(const char*)’
所以我试图注释掉 template<>
行高于尝试的特化,但后来我得到:
non-class, non-variable partial specialization ‘convertTo<std::set<T, std::less<_Key>, std::allocator<_CharT> > >’ is not allowed
我不明白。我不打算写一个部分特化?
我不想使用 template<class Container>
,因为我希望能够为不同的容器类编写特定的代码。 (我的代码中的其他模板类需要这个。)
关于如何做到这一点有什么建议吗?
最佳答案
无论出于何种原因,此问题的常见答案是转发到实现结构的静态方法。一个结构可以部分特化,所以这确实解决了这个问题。但通常使用重载会更好;这有多种原因,但在这里我只想说每个实现的样板文件更少。你可以这样做:
template <class T>
struct tag{}; // implementation detail
template<class T>
T convertTo(const char* str, tag<T>) {
T output;
stringstream ss(str, stringstream::in);
ss >> output;
return output;
}
int convertTo(const char* str, tag<int>) {
return atoi(str);
}
template<class T>
set<T> convertTo(const char* str, tag<set<T>>) {
set<T> S;
// TODO split str by comma, convertTo<T>(each element) and put into S
return S;
}
template<class T>
unordered_set<T> convertTo(const char* str, tag<unordered_set<T>>) {
unordered_set<T> S;
// TODO split str by comma, convertTo<T>(each element) and put into S
return S;
}
template <class T>
T convertTo(const char * s) {
return convertTo(s, tag<T>{});
};
所有带两个参数的 convertTo
现在都只是重载,这很好。面对 convertTo
的用户只需使用我们的小标记结构调用两个参数形式,以与部分特化完全相同的方式控制分派(dispatch)。
这项技术还有许多其他有趣的优点,例如使用额外的 tag
类结构和派生基转换更精确地控制重载决策的能力,ADL/2 阶段查找的实用程序,但这有点超出了这里的范围。
关于c++ - 模板化函数模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46325133/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!