为什么 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 中产生错误的示例,因为 X
是 MoveConstructible 而不是 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 中没有错误,因为只调用了默认构造函数。
以下是 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 中产生错误的示例,因为 X
是 MoveConstructible 而不是 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 中没有错误,因为只调用了默认构造函数。