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

unique_ptr自定义删除器多场景疑问:为何部分代码报错?

关于std::unique_ptr引用类型删除器的编译问题解析

我正在阅读Nicholai Jossutis所著的STL书籍,书中有一段代码:

D d;                                           // 删除器类型的实例
unique_ptr<int, const D&> p4(new int, D());    // 错误:右值删除器对象
                                               // 无法绑定到引用类型的删除器

对此我无法理解,因此编写了以下测试场景代码:

#include <memory>

class C_deleter_functor
{
public:
    void operator()(int* iptr) const
    {
        delete iptr;
    }
};

class deleter_functor
{
public:
    void operator()(int* iptr) 
    {
        delete iptr;
    }
};

int main()
{
    C_deleter_functor       d1;
    deleter_functor         d2;
    
    std::unique_ptr<int, const C_deleter_functor&> up1(new int, d1);                  // 1.OK
    std::unique_ptr<int, const deleter_functor&> up2(new int, d2);                    // 2.ERROR
    std::unique_ptr<int, const C_deleter_functor&> up3(new int, C_deleter_functor{}); // 3.ERROR
    std::unique_ptr<int, const deleter_functor&> up4(new int, deleter_functor{});     // 4.ERROR
}

下面逐个解释每个场景可行或报错的原因:

场景1:up1(编译通过)

  • 传入的d1是左值,可以正常绑定到const C_deleter_functor&类型的引用删除器;
  • C_deleter_functor的operator()是const成员函数,与引用类型的const限定完全匹配,后续调用删除器时不会有访问权限问题。

场景2:up2(编译报错)

  • deleter_functor的operator()是非const成员函数,但我们指定的删除器类型是const deleter_functor&——通过const引用调用非const成员函数违反了C++的const权限规则,编译器会直接报错。

场景3:up3(编译报错)

  • 这里传入的是临时对象C_deleter_functor{}(右值),虽然const T&语法上可以绑定右值,但std::unique_ptr对于引用类型的删除器有特殊要求:它不会接管右值删除器的生命周期。临时对象在当前语句执行结束后就会被销毁,后续unique_ptr调用删除器时会引用到已销毁的对象,属于未定义行为。因此标准直接禁止这种写法,编译器会报错。

场景4:up4(编译报错)

  • 同时存在场景2和场景3的两个问题:
    1. 传入的是临时右值,不符合引用类型删除器必须绑定左值的要求;
    2. deleter_functor的operator()是非const成员,无法通过const deleter_functor&调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:23:36