提问人:code707 提问时间:7/18/2018 最后编辑:curiousguycode707 更新时间:7/23/2018 访问量:79
为什么 CopyConstructible 定义提到“常量 T 的右值表达式”?
Why CopyConstructible definition mention "rvalue expression of const T"?
问:
以下是 cpppreference 的定义:
[https://en.cppreference.com/w/cpp/named_req/CopyConstructible][1]
要求:类型 T 满足 CopyConstructible,如果
类型 T 满足 MoveConstructible 和 Given
v,类型为 T 或常量 T 的左值表达式或右值表达式 类型 const T u,任意标识符 以下表达式 必须有效并具有其指定的效果
表达式后置条件 T u = v;你的价值相当于 v 的值。v 的值保持不变
T(v) T(v) 的值等于 v 的值。v 的值 没有变化。
我的问题是以下几行:
v,类型为 T 或常量 T 的左值表达式或右值表达式 类型 const T
我不明白这个“常量 T 类型的右值表达式”的一部分?为什么这个“const T 类型的右值表达式”出现在 CopyConstructible 的定义中?有人可以举例解释一下吗?MoveConstructible 的定义(这是 CopyConstructible 的前提条件)已经包含了该要求,不是吗?
答:
不,MoveConstructible 的定义只关心非 const 右值表达式,因为你不能从 const 移动。
CopyConstructible 扩展了它以涵盖 和 的其余可能性。T u = v;
T(v);
请注意,如果仅复制类型保持不变,则它仍然满足 MoveConstructible,因为“新值未指定”涵盖了这一点。rv
rv
举个例子
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
评论
只是一个在 C++11/14 中产生错误的示例,因为是 MoveConstructible 而不是 CopyConstructible:X
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 中没有错误,因为只调用了默认构造函数。
评论