我有这样的代码:
#include <set>
int main() {
int array[] = { 0 };
std::set<int> stdset(&array[1], &array[1]);
}它获取最后一个数组元素之后的元素地址,并将其转换为迭代器。基本上与std::vector::end()所做的相同。
这样做是合法的:
std::vector<int> vec;
std::set<int> stdset(vec.end(), vec.end());因为"last“迭代器是一个非包含限制。
对原始数组执行与第一个代码片段相同的操作合法吗?
发布于 2016-07-21 17:07:29
在C++中,您可以获取任何数组末尾之后的地址。
您不能解除引用并使用结果,但您可以将其与指向同一数组的其他指针进行比较,并将其与同一数组的末尾的其他指针进行比较。
您在OP中所做的是已定义的行为,并且表示一个空范围。
发布于 2016-07-21 17:07:42
不涉及任何转换。指针支持与随机访问迭代器相同的操作(一元*运算符、++和+运算符等)。因此可以用作迭代器。接受迭代器的标准库函数是在迭代器的类型上模板化的,因此它们将接受一个指针,而不会将其转换为任何值。
这一点,再加上指向超过数组末尾的指针是有效的(只要不取消引用它),意味着您的代码是正确的。
发布于 2016-07-21 17:25:02
您没有转换任何内容: pointers 是上的有效迭代器。
获取指向刚过数组末尾的元素的指针是合法的,但取消对此类指针的引用是不合法的。
ANSI,§5.7第5段:
当向指针添加或从指针中减去具有整型的表达式时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向距原始元素的元素偏移量,以便结果数组元素和原始数组元素的下标差等于整数表达式。换句话说,如果表达式P指向数组对象的第i个元素,则表达式(P)+N (等价地,N+(P))和(P)-N (其中N具有值n)分别指向数组对象的第i+n和i−n个元素,前提是它们存在。此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向数组对象的最后一个元素,如果表达式Q指向数组对象的最后一个元素,则表达式(Q)-1指向数组对象的最后一个元素。如果指针操作数和结果都指向同一数组对象的元素,或者指向数组对象的最后一个元素之后的元素,则求值不会产生overflow;否则,行为在fined之下。
我在网上的C++标准报价中没有找到对此的引用,我也没有C++标准的副本,所以我不能证明它仍然是关于C++的最新版本,但它可能是最新的。
TL;DR:您的代码是合法的。
https://stackoverflow.com/questions/38499130
复制相似问题