Byt*_*ter 5 c++ pointers iterator pointer-arithmetic undefined-behavior
在“使用 end()-- 迭代到 std::vector 的最后一个元素”的可接受答案中@barry 指出:
请注意,如果 vector::iterator 只是 T* (这将是有效的),则上面的第一种形式是错误的。无论如何,后两者都有效,因此更可取。
参考他的代码:
std::vector<int>::iterator it = --container.end();
std::vector<int>::iterator it = container.end() - 1;
std::vector<int>::iterator it = std::prev(container.end());
Run Code Online (Sandbox Code Playgroud)
这一观点在评论中存在争议,但没有明确的解决方案。这就是我的问题:第一个和第二个之间的语义差异究竟是什么?对于除 之外的结构上的迭代器,答案会有所不同吗vector?
Dre*_*ann 11
对于任何标准库容器,成员函数end()都会返回一个右值。在将其分配给变量之前,它是“临时的”。
递减运算符--不需要在右值迭代器上工作。您将修改一个临时变量,C++ 历来已采取措施避免这种情况。
因此,--container.end() 可以在符合标准的 C++ 编译器上进行编译。但也可能不会。
std::prev(container.end())将适用于每个符合标准的编译器。
回顾:
--container.end()可能无法编译。这取决于实施。container.end() - 1仅当容器使用随机访问迭代器时才会编译。std::prev(container.end())总是会编译。如果编译的话,所有三种形式都会产生相同的结果。