gpt4 book ai didi

c++ - 为什么在右值引用上使用 std::forward 会导致被引用对象的破坏?

转载 作者:行者123 更新时间:2023-11-30 01:15:55 25 4
gpt4 key购买 nike

#include <functional>
#include <memory>
#include <iostream>

struct A
{
~A() {std::cout << "~A()" << std::endl;}
};

void test(std::shared_ptr<A> ptr)
{
std::cout << (ptr ? "not empty" : "empty") << std::endl;
}

void forwarder(std::function<void(std::shared_ptr<A>)> f, std::shared_ptr<A>&& ptr)
{
f(std::forward<std::shared_ptr<A>>(ptr));
f(std::forward<std::shared_ptr<A>>(ptr));
}

void main()
{
forwarder([](std::shared_ptr<A> ptr){ test(ptr); }, std::make_shared<A>());
}

问题出在 forwarder 函数中。在第一次调用 test 之后,shared_ptr 被破坏了——很明显,还有 A 对象。所以在第二次调用 test 时,指针已经为空。我不明白为什么会这样。 std::forward 实现很简单。
所以,我有两个问题:
1. std::forward 是如何破坏传递给它的右值对象的?这是哪一段代码?
2. 如何解释这个 C++ 设计决策? ptr 还没有超出范围但已经死了,这对我来说似乎违反直觉。

最佳答案

它不是被破坏,而是被移走。有一个很大的不同。您对 std::forward 的使用也是完全不正确的,只是 FTR。

在这种情况下,std::forward<T>相当于std::move ,这意味着 ptr被移动到函数中。移动类似于复制操作,但源对象的状态被保留。因此,不出所料,后来它是空的,因为它已被移出。

f 的参数是从 let's-call-it- std::move(ptr) 返回的右值移动构建的.

关于c++ - 为什么在右值引用上使用 std::forward 会导致被引用对象的破坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27689731/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com