c++ - 在 C++14 中不指定对象的左值

标签 c++ language-lawyer c++14 lvalue

我在这里使用 N3936 作为引用(如果任何 C++14 文本不同,请更正此问题)。

在 3.10 左值和右值下,我们有:

Every expression belongs to exactly one of the fundamental classifications in this taxonomy: lvalue, xvalue, or prvalue.

但是 lvalue 的定义是:

An lvalue [...] designates a function or an object.

在 4.1 Lvalue-to-rvalue conversion 中,文本出现:

[...] In all other cases, the result of the conversion is determined according to the following rules: [...] Otherwise, the value contained in the object indicated by the glvalue is the prvalue result.

我的问题是:在左值不指定对象的代码中会发生什么?有两个典型的例子:

示例 1:

int *p = nullptr;
*p;
int &q = *p;
int a = *p;

示例 2:

int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);

哪些行(如果有的话)格式错误和/或导致未定义的行为?

引用例1:*p是左值吗?根据我的第一句话,它必须是。但是,我的第二个引用排除了它,因为 *p 没有指定一个对象。 (它当然也不是 xvalue 或 prvalue)。

但是如果你将我的第二个引用解释为 *p 实际上是一个左值,那么左值到右值的转换规则根本就没有涵盖它。您可以采用“任何未由标准定义的行为都是未定义行为”的包罗万象的规则,但是只要不执行左值到右值的转换,您就必须允许空引用存在。

历史:此问题在 DR 232 中提出.在 C++11 中,DR232 的解析确实出现了。引用自 N3337 Lvalue-to-rvalue conversion:

If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

它似乎仍然允许空引用存在——它只解决了对一个执行左值到右值转换的问题。 Also discussed on this SO thread

尽管 DR232 的分辨率不再出现在 N3797 或 N3936 中。

最佳答案

不可能创建对 null 的引用或对数组尾部元素的引用,因为第 8.3.2 节说(从 n3936 草案中读到)

A reference shall be initialized to refer to a valid object or function.

但是,并不清楚形成一个值类别为左值的表达式是否构成“引用的初始化”。恰恰相反,实际上临时对象是对象,引用不是对象,所以不能说*(a+n)初始化的是引用类型的临时对象。

关于c++ - 在 C++14 中不指定对象的左值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26290598/

相关文章:

c++ - 如何使用/使其在C++中插入日期类型(dd/mm/yyyy)时自动出现?

c++ - 指向引用的指针是非法的

c++ - 如何在 SQLite 中列出临时表/ View ?

c++ - 从文件中获取输入问题 C++

c++ - "structured bindings"与 "decomposition declarations"

c++ - 为什么 Multimap 不将一个索引处的所有值写入文本文件?

c++ - "C4649: attributes are ignored in this context"是什么意思?

c++ - 调用模板参数 constexpr 方法?

c - C的流中字符的含义

c++ - 模板指针参数包