M.M*_*M.M 6 c++ lvalue language-lawyer c++14
我在这里使用N3936作为参考(如果任何C++ 14文本不同,请更正此问题).
在3.10 Lvalues和rvalues下,我们有:
每个表达式都属于此分类法中的基本分类之一:lvalue,xvalue或prvalue.
但是左值的定义是:
的左值 [...]表示一个功能或一个对象.
在4.1 Lvalue-to-rvalue转换中,文本显示:
[...]在所有其他情况下,转换的结果根据以下规则确定:[...]否则,glvalue指示的对象中包含的值是prvalue结果.
我的问题是:在左值不指定对象的代码中会发生什么?有两个典型的例子:
例1:
int *p = nullptr;
*p;
int &q = *p;
int a = *p;
Run Code Online (Sandbox Code Playgroud)
例2:
int arr[4];
int *p = arr + 4;
*p;
int &q = *p;
std::sort(arr, &q);
Run Code Online (Sandbox Code Playgroud)
哪些行(如果有的话)格式不正确和/或导致未定义的行为?
参考实施例1:是*p左值?根据我的第一句话,它必须是.但是,我的第二个引文排除了它,因为*p没有指定一个对象.(它肯定不是xvalue或prvalue).
但是如果你将我的第二个引用解释*p为实际上是一个左值,那么它就不会被左值到右值转换规则所覆盖.您可以采用全部规则"标准未定义的任何内容是未定义的行为",但是只要没有执行左值到右值的转换,就必须允许空引用存在.
历史:此问题在DR 232中提出.在C++ 11中,DR232的分辨率确实出现了.引用N3337 Lvalue -to-rvalue转换:
如果glvalue引用的对象不是类型T的对象,并且不是从T派生的类型的对象,或者如果对象未初始化,则需要此转换的程序具有未定义的行为.
它似乎仍然允许空引用存在 - 它只清除了在一个上执行左值到右值转换的问题.也讨论了这个SO线程
DR232的分辨率不再出现在N3797或N3936中.
不可能创建对 null 的引用或对数组的末尾元素的引用,因为第 8.3.2 节说(从草案 n3936 中读取)
应初始化引用以引用有效的对象或函数。
然而,尚不清楚形成具有左值值类别的表达式是否构成“引用的初始化”。恰恰相反,事实上,临时对象是对象,而引用不是对象,所以不能说*(a+n)初始化一个引用类型的临时对象。
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |