C++ 减少begin()迭代器,然后再次增加它

C++ 减少begin()迭代器,然后再次增加它,c++,c++11,C++,C++11,这些声明是否符合标准 std::string str{"123"}; auto it = str.begin(); --it; ++it; // Does *it point to character '1' now? 我已经在g++4.7.2和clang++3.5上试过了,它返回'1'。 这是c++11中的标准行为吗 否,它无效 这是未定义的行为,因为24.2.6[双向.迭代器]指出,的后置条件是结果必须是可取消引用的。在您的示例中,由于它位于begin()之前,因此不满足此条件,因此该代码

这些声明是否符合标准

std::string str{"123"};
auto it = str.begin();
--it;
++it; // Does *it point to character '1' now?
我已经在g++4.7.2和clang++3.5上试过了,它返回
'1'
。 这是c++11中的标准行为吗

否,它无效

这是未定义的行为,因为24.2.6[双向.迭代器]指出,
的后置条件是结果必须是可取消引用的。在您的示例中,由于它位于
begin()
之前,因此不满足此条件,因此该代码是非法的


由于不需要进行诊断,它可能会起作用,但您不能(也不应该)依赖它。

尝试调试检查:推理不应该反过来吗?不满足前提条件,因为在
r=begin()
之前没有
s
,因此
r==++s
。因此,该操作是不允许的。@5gon12eder有多种方法来看待它和解释它。我使用了后置条件,因为它对我来说似乎是最明显的,我一直认为,如果你减少一个迭代器,它必须仍然指向一个有效的位置。YMMV@5gon12eder:任一原因都会将表达式置于未定义的行为中。还要注意的是,即使对于原始指针,
--
的行为是未定义的,如果指针开始指向数组的第一个元素或不是数组元素的对象。对于那些可能不同意的人(这个答案对某些人来说不是直观的),我将指出,在许多情况下,由于有多少迭代器类型碰巧被实现为指针,以及指针在大多数平台上是如何实现的,所以您通常会很幸运,而且它可以工作。虽然可能是这样,但它仍然是未定义的行为。如果那天它碰巧为你工作,你就是运气好。我推荐彩票!