为什么在结构化绑定后不使用 std::move 就不能返回 std::unique_ptr ?

Olp*_*pah 7 c++ std unique-ptr structured-bindings

当我尝试编译以下代码时,出现错误 C2280。我猜编译器正在尝试复制 unique_ptr 或其他东西。

#include <memory>

std::pair<int, std::unique_ptr<int>> CreatePair()
{
    std::unique_ptr<int> my_int(new int);
    return { 1, std::move(my_int) };
}
std::unique_ptr<int> GetUinquePtr()
{
    auto [ignore, unique_ptr] = CreatePair();
    return unique_ptr; // <- Build error C2280 attempting to reference a deleted function
}
int main()
{
    auto unique_ptr = GetUinquePtr();
}
Run Code Online (Sandbox Code Playgroud)

完整的错误消息:

error C2280: 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

如果我添加 std::move() 它就会起作用:

std::unique_ptr<int> GetUinquePtr()
{
    auto [ignore, unique_ptr] = CreatePair();
    return std::move(unique_ptr); // <- This works
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 std::tie 它工作正常:

std::unique_ptr<int> GetUinquePtr()
{
    std::unique_ptr<int> unique_ptr;
    std::tie(std::ignore, unique_ptr) = CreatePair();
    return unique_ptr; // <- This works
}
Run Code Online (Sandbox Code Playgroud)

那么是否需要在 unique_ptr 的结构化绑定之后显式键入 std::move 或者我在这里做错了什么?

mol*_*ilo 2

结构化绑定创建引用,您的代码或多或少相当于:

std::unique_ptr<int> GetUinquePtr()
{
    auto p = CreatePair();
    auto& ignore = p.first;
    auto& unique_ptr = p.second;
    return unique_ptr;
}
Run Code Online (Sandbox Code Playgroud)

返回引用将创建一个副本。

有了tie,它的工作原理就像这样:

std::unique_ptr<int> GetUinquePtr()
{
    std::unique_ptr<int> unique_ptr;
    unique_ptr = CreatePair().second;
    return unique_ptr;
}
Run Code Online (Sandbox Code Playgroud)