将 std::move shared_ptr 与条件运算符一起使用时的奇怪行为

问题描述 投票:0回答:0

我在

std::move
上使用
shared_ptr
编写一些 C++ 代码,得到了非常奇怪的输出。我已经简化了我的代码如下

int func(std::shared_ptr<int>&& a) {
    return 0;
}

int main() {
    std::shared_ptr<int> ptr = std::make_shared<int>(1);

    for (int i = 0; i != 10; ++i) {
        func(i == 9 ? std::move(ptr) : std::shared_ptr<int>(ptr));
    }

    if (ptr) {
        std::cout << "ptr is not null: " << *ptr << "\n";
    } else {
        std::cout << "ptr is null\n";
    }

    return 0;
}

我得到了输出

ptr is null

如我所料,我的

ptr
将在最后一个循环中移动(转换为
std::shared_ptr<int>&&
),并且由于
func
永远不会在
a
中窃取内存,所以我的
ptr
outside 将是非空的(事实证明实际上为空)。如果我更换

func(i == 9 ? std::move(ptr) : std::shared_ptr<int>(ptr));

带有 if-else 语句

if (i == 9) func(std::move(ptr));
else func(std::shared_ptr<int>(ptr));

输出将是

ptr is not null: 1

我对编译器的这种行为感到很困惑。

我尝试过使用不同标准版本和优化级别的 GCC 和 clang,并获得了相同的输出。有人可以为我解释

ptr
下的数据被盗的原因和位置吗?

c++ shared-ptr move-semantics conditional-operator move-constructor
© www.soinside.com 2019 - 2024. All rights reserved.