c++ - 即使复制构造函数不可用,返回仅移动类型也会编译

标签 c++ c++14

以下编译没有错误:

#include <memory>

std::unique_ptr<int> f() {
    std::unique_ptr<int> x(new int(42));
    return x;
}

int main() {
    std::unique_ptr<int> y = f();
}

我认为 f() 的返回值是由 x 复制初始化的,但是 std::unique_ptr 是一个 move-只打字。因为复制构造函数不可用,这怎么不是格式错误的呢?标准中的相关条款是什么?有没有什么地方说如果 f() 是只移动类型而不是 return 语句变成移动构造而不是复制构造?

最佳答案

I thought that the return value of f() was copy-initialized by x, but std::unique_ptr is a move-only type

f() 的返回值确实是从表达式x 复制初始化的,但复制初始化并不总是意味着复制构造。如果表达式是右值,则移动构造函数将由重载决议选择(假设存在移动构造函数)。

虽然 return x; 语句中的表达式 x 确实是一个左值(这可能会让您认为我刚才写的内容不适用), 在返回具有自动存储持续时间的命名对象的情况下,编译器应首先尝试将 id-expression 视为重载决策的右值。

What is the relevant clause in the standard? Is there somewhere that says if f() is a move-only type than a return statement becomes a move construction instead of a copy construction?

根据 C++ 标准的第 12.8/32 段([class.copy]/32,草案 N4296):

When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. [...]

关于c++ - 即使复制构造函数不可用,返回仅移动类型也会编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28410567/

相关文章:

类静态 constexpr 的 C++ 链接器错误

c++ - static const char* 上的 LINK 错误

c++ - 为什么 std::vector 构造函数通过复制接受初始值设定项列表?

结构散列的 C++ 无序集问题

c++ - 为什么我的 C++ 程序在执行 tcmalloc heap-checker 或 heap-profile 时使用大量内存

c++ - boost 共享指针 C++ : shared pointer unable to free resource on release

c++ - 复合文字是标准 C++ 吗?

c++ - 这个带有空捕获列表的 lambda 如何能够引用到达范围名称?

c++ - 扩展 std::thread 的 ref 对象传递范围

c++ - 如何将 opencv mat 写入 gstreamer 管道?