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

关于If-with-initializer生存期扩展与std::out_ptr代码是否存在潜在问题的疑问

关于If-with-initializer生存期扩展与std::out_ptr代码是否存在潜在问题的疑问

我最近看到P1132里把一段使用std::out_ptr配合if初始化器的代码标记为潜在的陷阱,实在搞不懂为什么这会是个问题。

先看P1132里提到的这段被标记为footgun的代码:

std::unique_ptr<foo_handle, foo_deleter> my_unique(nullptr);
if (get_some_pointer(std::out_ptr(my_unique)); my_unique) {
    std::cout << "yay" << std::endl;
} else {
    std::cout << "oh no" << std::endl;
}

P1132给出的理由是:例如,在同一个if语句中既完成初始化操作又测试智能指针的话,会以非常不合理的顺序进行生存期扩展。

但我始终想不通这里的问题所在:我们真正需要保证的是std::out_ptr的析构函数能在测试my_unique之前运行,从而完成对my_unique的重置。可if初始化器只会延长get_some_pointer()返回值的生存期(这里甚至都没把返回值赋值给任何变量),根本不会延长传入参数的生存期啊。

为了验证自己的想法,我写了一个小测试程序来模拟这个场景:

#include <iostream>

struct s {
    int i = []() { static int i = 0; return i++; }();
    s() { std::cout << i << ": ctor\n"; }
    ~s() { std::cout << i << ": dtor\n"; }
    operator bool() { std::cout << i << ": bool\n"; return false; }
};

template <typename... Ts>
s foo(Ts&&...) {
    return s{};
}

int main(int, const char**) {
    s x{};
    if (foo(s{}); x) {
        std::cout << " : true\n";
    } else {
        std::cout << " : false\n";
    }
}

我运行这段代码后,得到的输出是:

0: ctor
1: ctor
2: ctor
2: dtor
1: dtor
0: bool
 : false
0: dtor

从输出结果能清楚看到:foo()的参数临时对象和返回值临时对象,都是在测试x(对应原问题中的my_unique)之前就已经完成析构了。这完全符合我的预期——临时对象的析构会在if初始化器执行完毕、进入条件判断逻辑之前完成。

那我是不是漏掉了什么关键细节?还是说P1132里的这个说法其实并不准确?


内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:05:29