为什么 CopyConstructible 定义提到 "rvalue expression of const T"?

Why CopyConstructible definition mention "rvalue expression of const T"?

以下是 cppreference 的定义:

[https://en.cppreference.com/w/cpp/named_req/CopyConstructible][1]

Requirements: The type T satisfies CopyConstructible if

The type T satisfies MoveConstructible, and Given

v, an lvalue expression of type T or const T or an rvalue expression of type const T u, an arbitrary identifier The following expressions must be valid and have their specified effects

Expression Post-conditions T u = v; The value of u is equivalent to the value of v. The value of v is unchanged

T(v) The value of T(v) is equivalent to the value of v. The value of v is unchanged.

我的问题如下:

v, an lvalue expression of type T or const T or an rvalue expression of type const T

我不明白其中的一部分"rvalue expression of type const T"?为什么这个 "rvalue expression of type const T" 存在于 CopyConstructible 的定义中?有人可以举例说明吗? MoveConstructible 的定义(它是 CopyConstructible 的先决条件)已经包含了这个要求,不是吗?

不,MoveConstructible 的定义只关心非 const 右值表达式,因为你不能从 const 移出。

CopyConstructible 扩展它以涵盖 T u = v;T(v); 的剩余可能性。

请注意,如果保持 rv 不变,仅复制类型仍然满足 MoveConstructible,因为 "The new value of rv is unspecified."

涵盖了这一点

举个例子

struct Foo {
    void Bar() { /* modify Foo somehow */ }
};

const Foo createFoo() { return {}; }

Foo foo = createFoo(); // Must copy, as the return value is const

这种构造出现在 C++11 之前的代码中,作者希望禁止像 createFoo().Bar(); 这样的构造,因为修改临时 Foo.[=18 是错误的=]

只是一个在 C++11/14 中产生错误的示例,因为 XMoveConstructible 而不是 CopyConstructible :

struct X {
   X() = default;
   X(const X&) = delete;
   X(X&&) = default;
};

const X f1() { return X{}; }
X f2() { return X{}; }

int main() {
   X x1 = f1(); // copy-initialization from const rvalue: ERROR
   X x2 = f2(); // copy-initialization from rvalue: OK
}

请注意,在 C++17 中没有错误,因为只调用了默认构造函数。