我有一个像这样定义的类
class A
{
private:
map<int,vector<int>> m;
public:
vector<int> GetJsonVal(int k)
{
return m[k];
}
};
我想把它改成像这样的东西
template<class T>
class A
{
private:
map<int,T> m;
public:
T GetJsonVal(int k)
{
return m[k];
}
};
但是,我还有许多其他地方明显只使用A
类型,所以如果我将我的班级改为后者,我必须解决很多问题,即将所有内容改为A<type>
,我不知道不想要。在这些地方,我只需void func(A*p)
或A& r=....
那么,我怎么能在我喜欢的任何地方使用A<float>
和A
?
答案 0 :(得分:3)
因此,我想到的最简单,最清晰的解决方案是type alias:
template <typename T>
class Tool {
private:
map<int,vector<T>> m;
public:
vector<T> GetJsonVal(int k) {
return m[k];
}
};
using A = Tool<int>;
现在,旧代码可以继续使用A
,所有新代码都可以使用Tool<int>
或其他类型别名。
答案 1 :(得分:1)
你可以使用type-erasue,但是仍然需要在这里和那里更新代码......一种方法可能是这样的:
class A {
map<int, boost::any> m;
template <typename T>
T valueAs(int idx);
};
A a;
a.valueAs<int>();
您可以通过实现验证存储的类型和检索的类型是否相同。然后,您可能希望转到A
的所有现有用途并强制执行检查(或检查潜在错误)。
也就是说,如果您想支持A
内的混合类型...如果每个A
只能包含特定类型,则只需使用ATmpl
类型即可问题中的内容,然后typedef ATmpl<vector<int>> A;
。此时你仍然需要修复一些用例(特别是:前向声明)......
答案 2 :(得分:0)
使用模板类专业化,我想说
template <> class A<vector<int>>
{
// all your old code here
}
应该有用......
更新
为了清楚起见,模板专业化和类型别名之间存在语义差异。使用模板专业化,你可以将你的(真实的,测试的和bug兼容的)代码放入专业化中,并在新的制作中的其他地方使用新的和有光泽的(但可能有错误的代码),以后当你填写它时你可以删除专业化并仅使用新代码。对于类型专业化,它立即是新代码...