问题标签 [lvalue-to-rvalue]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 将从函数返回的右值分配给另一个右值
这对我来说没有意义。如何以及为什么允许这样做?它是未定义的行为吗?如果一个函数返回一个右值,那么如何将一个右值设置为另一个右值?如果我用任何原始类型尝试这个,它会像我预期的那样给我一个错误。
我知道左值是内存中的一个位置,那么该函数是否会创建一个临时左值(右值?)并将其分配给另一个左值?有人可以解释这种语法是如何工作的吗?
c++ - 转换后是右值还是左值
这里的代码在类型转换后测试左值或右值:
在 gcc链接中,结果如下所示,表明类型转换后产生的右值:
但在 VC++2010 中,只有当它是类类型时,才会显示右值:
那么当类型转换为 int 时,它是编译器错误还是只是一些未定义的行为?
c++ - 为什么右值引用被通用引用变成左值引用
我想当通用引用参数与右值引用参数匹配时,会返回一个右值引用参数。但是,我的测试表明,右值引用被通用引用函数模板变成了左值引用。为什么会这样?
在 GCC 和 VC++2010 中,结果如下:
换句话说, in 的参数t
是f2
一个右值引用,但是当传递给 时f1
,参数变成了一个左值引用。它不应该保留右值f1
吗?
c++ - std::forward 实现之间的区别
最近我一直在尝试理解移动语义并提出了一个问题。
这个问题已经在这里讨论过了。
我实现了第一个变体并检查它是否返回左值或右值:
因此,如果我传递 l-value,它会返回 l-value(编译,因为我可以从 l-value 获取地址),如果我这样做:
我的代码无法编译,因为 my_forward 返回了 r 值。在上面的问题中,他们说这个实现和标准实现之间的区别(分别使用 std::remove_reference 和 2 个不同的参数与 & 和 && )是我的实现一直返回左值,但正如我所展示的那样返回右值和左值。
所以我想知道,为什么我不能像那样实现 std::forward ?在什么特定情况下,它会显示标准之间的差异?另外,为什么我应该将 T 指定为模板并且不能让它用参数类型定义自己?
c++ - [expr.ref]/2 中的左值到右值转换
对于第一个选项(点),第一个表达式应是具有完整类类型的泛左值。对于第二个选项(箭头),第一个表达式应是具有指向完整类类型的指针的纯右值。表达式 E1->E2 被转换为等价形式 (*(E1)).E2;[expr.ref] 的其余部分将仅处理第一个选项(点)。68在任何一种情况下,id 表达式都应命名该类或其基类之一的成员。[ 注意:因为类名插入到其类范围内(子句 [class]),所以类名也被认为是该类的嵌套成员。— end note ] [ 注意:[basic.lookup.classref] 描述了如何在 . 和 -> 运算符。——尾注]
根据本段,在p
下面的代码段中应用了左值到右值的转换。但不适用于a
. 为什么标准为第一个选项(点)规定了一个左值,为第二个选项(箭头)规定了一个纯右值?
c++ - 可以将作用域末尾的左值视为右值吗?
编辑:考虑以下2个示例:
在第 (1) 行和第 (2) 行的两个示例y
中,它的生命周期即将结束,即将被销毁。很明显,它可以被视为右值并在两种情况下都可以移动。在 (1) 中,它的内容可以移动到x
(2) 中的临时实例中X().y_
。
我的问题是:
1) 它会在上述任何一个例子中移动吗?(a) 如果是,根据什么标准规定。(b) 如果没有,为什么不呢?这是标准中的遗漏还是我没有想到的其他原因?
2)如果上述答案是否定的。在第一个示例中,我可以将 (1) 更改x = std::move(y)
为强制编译器执行移动。在第二个示例中我可以做什么来向编译器指示y
可以移动的内容?return std::move(y)
?
注意:我故意返回Y
而不是X
在 (2) 中的实例以避免 (N)RVO。
c++ - 为什么 C++ 默认不移动构造右值引用?
说我有以下功能
为什么我需要用 转换param
回右值std::move()
?param
因为它在函数签名中被声明为右值引用,所以它的类型是右值不是很明显吗?不应该仅根据这个原则在这里自动调用移动构造函数吗?
为什么默认情况下不会发生这种情况?
c++ - 对于不确定值的无符号字符类型的左值到右值转换标准中特殊语言的意义是什么
在 C++14 标准 (n3797) 中,关于左值到右值转换的部分内容如下(强调我的):
4.1 左值到右值的转换[conv.lval]
非函数、非数组类型的 glvalue (3.10)
T
可以转换为纯右值。如果T
是不完整类型,则需要进行此转换的程序格式错误。如果T
是非类类型,则纯右值的类型是 的 cv 非限定版本T
。否则纯右值的类型是T
。当在未计算的操作数或其子表达式中发生左值到右值的转换(第 5 条)时,不访问包含在引用对象中的值。在所有其他情况下,转换结果根据以下规则确定:
- 如果
T
是一个(可能是 cv 限定的)std::nullptr_t
,那么结果是一个空指针常量。- 否则,如果
T
具有类类型,则转换复制初始化T
来自泛左值的临时类型,并且转换的结果是临时的纯右值。- 否则,如果泛泛值引用的对象包含无效的指针值,则行为是实现定义的。
- 否则,如果
T
是(可能是 cv 限定的)无符号字符类型,并且泛左值所引用的对象包含不确定值,并且该对象没有自动存储持续时间,或者泛左值是一元运算符的操作数,&
或者它是绑定到一个引用,结果是一个未指定的值。- 否则,如果泛左值引用的对象具有不确定的值,则行为未定义。
- 否则,glvalue 指示的对象是纯右值结果。
- [注:另见 3.10]
这一段的意义是什么(粗体)?
如果这一段不在这里,那么它适用的情况将导致未定义的行为。通常,我希望unsigned char
在具有不确定值的情况下访问一个值会导致未定义的行为。但是,这一段意味着
- 如果我实际上并没有访问字符值,即我立即将它传递给
&
或将其绑定到引用,或者 - 如果
unsigned char
没有自动存储期限,
然后转换产生一个未指定的值,而不是未定义的行为。
我是否正确得出以下结论:该程序:
由标准明确定义,并且必须输出 500 个未指定整数的序列,而同一个程序 whereT = int
会有未定义的行为?
IIUC,使其 UB 读取具有不确定值的内容的原因之一是允许优化器积极消除死存储。因此,本段可能意味着符合标准的编译器在unsigned char
使用unsigned char
.
假设我理解正确,这条规则的基本原理是什么?何时能够读取unsigned char
具有不确定值并获得未指定结果而不是 UB 有用?我有这样的感觉,如果他们在制定这部分规则时付出了这么多努力,他们就有动力帮助他们关心的某些代码示例,或者与标准的其他部分保持一致,或者简化其他问题. 但我不知道那可能是什么。
c++ - 类类型的左值到右值转换:是否涉及复制?
(我之前问过这个问题,但没有给出一个可行的例子,所以我删除了前一个。我希望在这个问题上我得到了正确的例子。)
案子:
据我了解,ref = s2;
包括 l2r 转换,因为它是每个 cppreference 期望的“内置直接分配”,并且右值作为其正确的参数。
我已经阅读了一些关于左值到右值转换的 SO 问题,但我仍然不确定它是否涉及对象的复制,如果涉及,它是哪种复制。
假设我们正在谈论类类型。
来自 [conv.lval]/2:
否则,如果 T 具有类类型,则转换从泛左值复制初始化 T 类型的临时,并且转换的结果是临时的纯右值。
因此,作为左值到右值转换的一部分,涉及到复制初始化。
因此,以用户定义的复制构造函数为例ref = s2;
,例如打印“Copying”,在上述语句的执行过程中会打印“Copying”吗?
嗯,显然不会。但这意味着我在这里误解了一些东西。
左值到右值转换期间的复制初始化是否类似于普通的 memcpy 而不是完全意义上的复制初始化?
这一切是如何运作的?:)