我在这里使用 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/