gpt4 book ai didi

c++ - 模板化函数模板特化

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:58 26 4
gpt4 key购买 nike

我想为模板函数编写一个特化,它所特化的类型本身就是一个模板化类型。 (我使用的是 C++11 或更高版本。)

在下面的示例代码中,我有通用函数 convertToint 的工作特化, 允许我使用 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com