如何修改智能指针管理列表模板以支持指针类型作为模板参数?
解决TList模板参数为指针类型的编译错误
需要修正的关键问题
- 补充必要头文件:
std::shared_ptr和std::remove_pointer都定义在<memory>头文件中,原代码未显式包含,需添加该头文件。 - 为依赖类型添加
typename关键字:模板中std::remove_pointer<T>::type属于依赖于模板参数的名称,编译器无法提前判断其为类型,必须用typename前缀明确标记。 - (可选)用类型别名简化重复的类型声明,提升代码可读性。
修正后的完整代码
#include <iostream> #include <list> #include <memory> // 必须包含的头文件 class Obj { public: Obj(){std::cout << "created " << this << "\n";} ~Obj(){std::cout << "deleted " << this << "\n";} }; template <class T> class TList : public std::list<std::shared_ptr<typename std::remove_pointer<T>::type>> { // 类型别名简化重复声明 using ElementType = typename std::remove_pointer<T>::type; using BaseList = std::list<std::shared_ptr<ElementType>>; public: TList() = default; ~TList() = default; TList& operator<<(T t) { std::shared_ptr<ElementType> p(t); BaseList::push_back(p); return *this; } }; int main(int argc, char *argv[]) { TList<Obj*> list; list << new Obj; return 0; }
错误原因说明
- C4346警告:
std::remove_pointer<T>::type是依赖于模板参数T的名称,编译器默认会将其视为类成员而非类型,必须用typename前缀明确告知编译器这是一个类型。 - C2923/C3203错误:由于缺少
typename,编译器无法识别std::remove_pointer<T>::type为有效类型,导致std::shared_ptr模板实例化失败,进而引发类型不匹配错误。 - 头文件缺失:原代码未包含
<memory>,部分编译器可能通过间接依赖找到定义,但标准要求必须显式包含该头文件才能使用std::shared_ptr和类型萃取工具。
内容的提问来源于stack exchange,提问作者NiHoT
相关产品推荐
相关产品推荐

