它以前曾以各种形式被问过,但由于语言规范在这方面似乎是动态的(或者至少是当一些关于这个问题的 SO 讨论发生时动态的),它根据任何最新的发展(如果有的话)重新审视这个问题可能是有意义的。
因此,问题又是,&
和下标的组合是否是获取指向数组的假想尾后元素的指针的有效方法
int a[42] = {};
&a[42];
它在 C++98 中被认为是未定义的。但是现代 C++ 呢?我们已经看到DR#232 ,但出于某种原因仍处于“起草”状态,并且绝对不在标准文本中(自 C++14 起)。问题是否仍然悬而未决,还是已通过其他方式解决?
有趣的是 DR#315似乎公开允许通过空指针调用非静态成员函数 p
(!) 基于“*p
在 p
为空,除非左值被转换为右值”。感觉 DR#315 的决议是暂时基于 DR#232 所谓的灌篮 future 决议,但后者未能实现。从这个角度来看,DR#315 真的是 NAD 吗?
此外,自 C++11 以来,库规范将 可取消引用 迭代器定义为 *it
表达式有效的迭代器,在 std 的情况下: :vector
会/可能会在很大程度上将问题委托(delegate)给上述原始数组问题,并且显然为可撤销的 std::vector::end()
迭代器打开了大门。这可能使以下代码有效
std::vector<int> v(42);
&v[42];
它真的有效吗? SO 上的一些较旧的答案明确指出取消引用标准 end()
迭代器始终未定义。但在该语言的后 C++11 版本中,它似乎并不那么明确。该标准表示库实现“从不假定”结束迭代器是可解引用的,这意味着它们不再是无条件不可解引用的。
附言我已经看过这个讨论Lvalues which do not designate objects in C++14 , 但它似乎特别关注引用初始化的有效性,我不想在这里提到这一点。
最佳答案
据我所知,您在 &v[42]
(或 &a[42]
)表达式中取消引用它,它是未定义的。
基于 N4140:
[expr.unary.op]/1
The unary * operator performs indirection : the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
我不认为数组最后一个元素之后的非元素被视为对象。
关于c++ - 一个尾数下标的明显规范不足:对于原始数组和 std::vector。已经果断解决了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860732/