【发布时间】:2018-01-29 02:13:06
【问题描述】:
(我之前问过这个问题,但没有给出一个可行的例子,所以我删除了前一个。我希望在这个问题上我得到了正确的例子。)
案例:
#include <iostream>
struct S
{
S() = default;
S(const S &)
{
std::cout << "Copying" << std::endl;
}
S& operator=(const S &)
{
std::cout << "Copy assignment" << std::endl;
return *this;
}
};
int main()
{
S s{};
S s2{};
S &ref = s;
ref = s2;
}
据我了解,ref = s2; 包括 l2r 转换,因为它是每个 cppreference 期望的“内置直接赋值”,并且右值作为其正确参数。
我已经阅读了一些关于左值到右值转换的 SO 问题,但我仍然不确定它是否涉及对象的复制,如果涉及,它是什么类型的复制。
假设我们正在讨论类类型。
来自 [conv.lval]/2:
否则,如果 T 具有类类型,则转换会从泛左值复制初始化 T 类型的临时值,并且转换的结果是临时值的纯右值。
因此,作为左值到右值转换的一部分,涉及到复制初始化。
以ref = s2; 为例,使用用户定义的复制构造函数,例如prints 'Copying',在上述语句的执行过程中会打印出'Copying'吗?
嗯,显然不会。但这意味着我在这里误解了一些东西。
左值到右值转换期间的复制初始化是不是类似于普通的 memcpy,而不是完全意义上的复制初始化?
这一切是如何运作的? :)
【问题讨论】:
-
标准不是学习C++的好方法。我会推荐one of the books。在这种情况下,
ref = s2不会调用副本 构造函数,而是调用副本 赋值运算符。 -
从标准中学习 C++ 有点像通过阅读关于反向公司合并的法庭诉讼程序以及在知识产权讨论中的作用来学习法律。它可能会为您提供一些您需要的核心概念,但它会让您感到困惑,并且有时会过于关注当前与您的品味无关的细节。
-
@Barry 好吧,我已经阅读了几乎所有的 Meyers 和一些 Sutter :) 以及关于 l2r 的十几个 SO 问题 :) 在某些情况下它并没有让事情变得更容易,所以 is 需要达到标准 :) 我知道复制赋值运算符被调用,是的,我已经更新了示例:请注意,我有一个 ref 接受复制赋值运算符,但是 l2r似乎仍然适用;该 l2r 是否执行引用中所写的复制初始化?除非你有一整包 SO 代表,否则每个人都认为你对 lang 一无所知,这有点令人不安:(
-
@ledonter 叹了口气。我正在努力帮助你。如果您想从我的评论中推断出它来自恶意,并且仅基于您在本网站上的声誉而带有贬义,那完全取决于您。
标签: c++ c++14 copy-constructor lvalue-to-rvalue value-categories