C++模板特化如何实现可接受任意同模板实例的类方法?
实现方案
你只需要在Foobar<char>特化版本中,将接收任意类型实例的构造和赋值运算符声明为成员模板即可,编译器会自动推导模板参数,完全不需要手动输入尖括号。
完整实现代码
#include <utility> // 主模板 template<class T> class Foobar { public: Foobar() = default; Foobar(const Foobar<T>&) = default; Foobar(Foobar<T>&&) = default; Foobar<T>& operator=(const Foobar<T>&) = default; Foobar<T>& operator=(Foobar<T>&&) = default; }; // char类型特化 template<> class Foobar<char> { public: Foobar() = default; // 可选择保留char版本自身的拷贝/移动函数,也可删除 Foobar(const Foobar<char>&) = default; Foobar(Foobar<char>&&) = default; Foobar<char>& operator=(const Foobar<char>&) = default; Foobar<char>& operator=(Foobar<char>&&) = default; // 通用构造/赋值:支持任意类型的Foobar入参 template<typename AnyT> Foobar(const Foobar<AnyT>& foo) { // 在此实现类型擦除逻辑 } template<typename AnyT> Foobar(Foobar<AnyT>&& foo) { // 在此实现移动构造的类型擦除逻辑 } template<typename AnyT> Foobar<char>& operator=(const Foobar<AnyT>& foo) { // 在此实现拷贝赋值的类型擦除逻辑 return *this; } template<typename AnyT> Foobar<char>& operator=(Foobar<AnyT>&& foo) { // 在此实现移动赋值的类型擦除逻辑 return *this; } }; // 测试调用 int main() { Foobar<int> fooInt; Foobar<char> fooMemory; // 无需手动指定模板参数,编译器自动推导 fooMemory = std::move(fooInt); Foobar<double> fooDouble; Foobar<char> fooMemory2 = fooDouble; return 0; }
额外说明
- 通用成员模板同时支持
Foobar<char>自身类型的入参,如果你不需要单独优化自身类型的拷贝/移动逻辑,可以直接删除特化类里默认的四个自身类型拷贝/移动函数,通用模板会自动覆盖对应场景。 - 类型擦除的逻辑可参考
shared_ptr<void>的实现,在通用构造/赋值函数中保存原始数据指针、销毁函数、数据长度等必要信息到Foobar<char>的成员变量中即可。
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

