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

C++23中用静态operator()作unique_ptr删除器是否合规?编译疑问解析

C++23中std::unique_ptr静态删除器代码的合法性解析

一、代码是否符合C++23标准?

这段代码是符合C++23标准的。

std::unique_ptr的第二个模板参数Deleter仅需满足可调用要求:该类型的实例能够接受int*类型参数并执行删除逻辑即可。这里我们用静态成员函数custom_deleter::operator()的指针作为Deleter类型,函数指针本身具备可调用性,同时构造unique_ptr时也传入了对应的函数指针实例,完全符合unique_ptr的构造规则,属于标准允许的写法。

二、移除&导致编译错误的原因

去掉decltype(&custom_deleter::operator())中的&后,decltype的参数变为custom_deleter::operator()——这是一个重载集的名字,而非明确的表达式。

C++语法中,decltype需要作用于确定的表达式或类型名。直接写custom_deleter::operator()时,编译器无法从这个重载集名字中锁定具体的函数(哪怕这里只有一个重载,语法上仍会被视为重载集),因此无法推导出有效类型,最终触发编译错误。而加上&后,&custom_deleter::operator()是获取静态成员函数指针的明确表达式,编译器能推导出对应的函数指针类型void(*)(int* const),此时decltype就能得到正确的类型。

三、Deleter模板参数必须是函数指针类型吗?

完全不需要。std::unique_ptr的Deleter可以是任何满足可调用要求的类型,常见替代类型包括:

  • 带非静态operator()的仿函数类:
    struct CustomDeleter {
        void operator()(int* ptr) {
            delete ptr;
            std::fputs("Deleted\n", stdout);
        }
    };
    std::unique_ptr<int, CustomDeleter> ptr(new int{5});
    
  • lambda表达式类型:
    auto deleter = [](int* ptr) {
        delete ptr;
        std::fputs("Deleted\n", stdout);
    };
    std::unique_ptr<int, decltype(deleter)> ptr(new int{5}, deleter);
    
  • std::function包装类型:
    std::unique_ptr<int, std::function<void(int*)>> ptr(
        new int{5},
        [](int* p) { delete p; std::fputs("Deleted\n", stdout); }
    );
    

只要某类型的实例能被调用并处理对应指针参数,就可以作为unique_ptr的Deleter。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 02:45:04