You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改智能指针管理列表模板以支持指针类型作为模板参数?

解决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;
}

错误原因说明

  1. C4346警告:std::remove_pointer<T>::type是依赖于模板参数T的名称,编译器默认会将其视为类成员而非类型,必须用typename前缀明确告知编译器这是一个类型。
  2. C2923/C3203错误:由于缺少typename,编译器无法识别std::remove_pointer<T>::type为有效类型,导致std::shared_ptr模板实例化失败,进而引发类型不匹配错误。
  3. 头文件缺失:原代码未包含<memory>,部分编译器可能通过间接依赖找到定义,但标准要求必须显式包含该头文件才能使用std::shared_ptr和类型萃取工具。

内容的提问来源于stack exchange,提问作者NiHoT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:45:40