law*_*log 6 c++ templates specialization c++11
我想为模板函数编写一个特殊化,其中针对它的特殊化类型本身就是一个模板化类型。(我使用的是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;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ 6.3.0,我收到错误消息:
too many template parameter lists in declaration of ‘std::set<T> convertTo(const char*)’
Run Code Online (Sandbox Code Playgroud)
因此,我尝试注释掉template<>尝试的专业化以上的内容,但随后得到:
non-class, non-variable partial specialization ‘convertTo<std::set<T, std::less<_Key>, std::allocator<_CharT> > >’ is not allowed
Run Code Online (Sandbox Code Playgroud)
我不明白 我不想写部分专业化知识吗?
我不想使用template<class Container>,因为我希望能够为不同的容器类编写特定的代码。(我的代码中的其他模板类需要此。)
任何建议如何做到这一点?
部分特化是指指定模板类型的一部分,而不是整个类型。例如,
template <>
template<class T> set<T> convertTo<set<T>>(const char* str)
Run Code Online (Sandbox Code Playgroud)
set<T>如果允许部分函数特化,则将部分特化。
处理此问题的两种主要方法是通过删除该template<>部分来代替重载,或者更好地切换到使用模板类专业化。重载的问题在于,如果您使用另一个模板(如set<T>)或单个类型(如int)重载,它看起来会有些不同,并且混合专业化和重载几乎肯定不会按您的预期工作。
因此,模板类专业化通常是最好的方法,可以这样做:
// Generic version
template <typename T>
class Converter {
public:
T operator() (const char* str) {
T output;
stringstream ss(str, stringstream::in);
ss >> output;
return output;
}
};
template <>
class Converter<int> {
public:
int operator() (const char* str) {
return atoi(str);
}
};
// ...
template <typename T>
T convertTo(const char* str) {
return Converter<T>{}(str);
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以毫无问题地在课程中使用您想要的任何类型的专业化。