问题标签 [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++ - 在等号左侧使用右值引用的规则是什么?
所以我一直在学习右值和右值引用,并且在试验时遇到了一些代码,我无法解决这些错误。
我只是想知道如何处理 std::strings 和 int 的右值引用有什么区别,以及为什么一个有效而一个无效。
我正在使用带有 C++17 的 Visual Studio 2019
c - void 表达式中的未定义行为
是否需要 C 实现来忽略在评估 void 表达式期间发生的未定义行为,就好像评估本身从未发生过一样?
考虑到 C11,6.3.2.2 §1:
如果任何其他类型的表达式被评估为 void 表达式,则其值或指示符将被丢弃。(评估 void 表达式的副作用。)
这与用于防止编译器警告未使用变量的常用习语有关:
但是,如果我们有未定义的行为,例如:
我可以安全地声称该程序不包含未定义的行为吗?该标准说“它的值或指示符被丢弃”,但“表达式(...)被评估(...)”,所以评估似乎发生了。
GCC/Clang 确实报告了未定义的行为,因为在这种情况下很明显,但在一个更微妙的例子中它们没有:
即使有-O0
,GCC 和 Clang 都不会评估1/0
。但是即使没有演员阵容也会发生这种情况,所以它不具有代表性。
将论点推向极端,(void)a
在我的第一个示例(a
未初始化的地方)中的简单评估不会系统地触发未定义的行为吗?
ISO C11 6.3.2.1 §2 确实提到:
如果左值指定了一个可以使用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明并且在使用之前未对其进行分配),行为未定义。
但是,在附件 J.2 未定义行为中,措辞略有不同:
在以下情况下,行为未定义:
(...)
一个左值指定一个可以用寄存器存储类声明的自动存储持续时间的对象,在需要指定对象的值的上下文中使用,但该对象未初始化。(6.3.2.1)。
这个附件确实导致了这样一种解释,即void
在其评估期间包含未定义行为的表达式实际上并未被评估,但由于它只是一个附件,我不确定它的论证权重。
c++ - C++ 传递向量(左值到右值)
假设您将 2vectors
传递给函数作为lvalue references
. 后来你意识到,你可以使用递归并vectors
使用它们的iterators
.
如果我继续编写一些util
函数来使用它们vecotrs
,这会是一个合适的策略rvalues
吗?或者我应该以任何方式避免这种情况?
简化模式:
现实的例子(LeetCode 105):
c - `(i) = 1` 在标准 C 中是非法的吗?
我正在编写一个遵循这个标准的 C 编译器,如果我解析这样的语句:
我的编译器会报告一个错误,指出这(i)
是一个右值,不应该是可分配的。
我检查了代码和规则,发现:在赋值表达式语义中:
赋值运算符应具有可修改的左值作为其左操作数。
赋值表达式在赋值后具有左操作数的值,但不是左值。
就我而言,有两个赋值表达式:
括号中的(i) = 1
和i
。所以(i)
应该是一个右值。
所以我的问题是:
(i) = 1
在这个 C 标准中是非法的吗?
c - 使用未初始化的变量而不调用未定义的行为
从 6.3.2.1(强调我的)
如果左值指定了一个可以使用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明并且在使用之前没有对其进行分配) ),行为未定义。
这意味着,如果无法使用寄存器存储类声明自动对象(获取它的地址):
根据 6.3.2.1,if (x == 2)
在我使用未初始化对象的值的地方没有未定义的行为。如果这是真的,并且这里没有 UB,那么定义的行为是什么?x
根据标准,我应该期待什么?
c++ - 左值到右值的转换是否发生在类类型上?
实际上,我在网上看到的每一个左值到右值转换的例子都与基本类型有关,例如int
etc。
我自己找不到适用于类类型的 l2r 示例;在所有看似适用的示例中,通常有一个函数涉及 lvalue-ref(如 copy-ctor),l2r 似乎被抑制(参见例如这个问题)。
然而,在 l2r 本身的描述中有一个关于类类型的子句(来自 [conv.lval]):
转换结果根据以下规则确定:
<...> 如果 T 具有类类型,则转换从泛泛值复制初始化 T 类型的临时,并且转换的结果是临时的纯右值。
有人可以举一个这个条款的例子吗?我不能。
c++ - Clang vs G++ 左值到右值转换
与此 相关的问题。通过跟踪slt_pair. h
and move. h
,似乎Clang和G++之间的区别在于内部。我试图模拟对象的分配(pair.first)与实现相同,输出与Clangstd_pair.h
输出相同,它是合理的输出,但是为什么在使用对时它会发生变化。
Clang如何处理转换lvalue
以及rvalue
这些不同输出的真正原因。
任何意见都非常感谢,谢谢。
更新:我在接受的评论部分得到了令人满意的答案。
c++ - 我应该明确地=删除非常量右值引用限定函数吗?
我有一个类A
,它有一个不能在临时对象上调用的非常量成员函数foo
,这就是它的样子:
如果我必须显式删除版本foo
,因为 const rvalues 可以绑定到 const lvalues,实际上下面的代码编译得很好const
const&&
所以有理由显式删除一个 const rvalue ref 限定函数,非 const 函数也有什么原因吗?
c++11 - C2664 无法转换为 && 值
编译器希望我的左值成为右值引用,我不明白为什么。
我的问题是:
- 为什么“dataLen”是 const,即使它被声明为非 const 并且 lambda 被告知默认通过引用捕获?
- 为什么编译器尝试转换为右值引用“unsigned __int64 &&”,即使它被声明为 tupleByteVector_content 的“unsigned long long”(无右值引用)?
我认为这是因为 lambda 捕获,但请参阅下面的简化工作流程:
编辑:我能够编译这个元组:
但是随后向量的 push_back 给出了错误:错误 C2663: [...] ::push_back": 对于 2 个重载,this 指针没有转换(我自己免费翻译成英文)
c++ - 如何将临时对象作为非常量引用传递给成员函数?
我们正在创建一个旨在从当前模块发送信息的类(细节与这个问题无关)。这种类型的对象被创建并填充了需要发送的部分数据,然后传递给(不同的类)成员函数。该函数为对象提供其余数据,然后通过对象本身的调用触发发送。因为传入的信息是动态的,所以信息传输对象是一个临时对象,是用最新数据创建的。我们列出的设计在下面的精炼源代码中,但 gcc/C++ 不允许这样做,并给出显示的错误。
问题是,我们如何使用可以被调用函数修改和使用的临时对象(避免内存泄漏)来完成预期的行为?
gcc 编译器错误:
提炼的示例代码:
infoxfer.cpp: