Hi *_* SO 0 c++ iteration iterator stdlist language-lawyer
标准是否保证
--list.begin() == list.end()
总是成立并且它实际上是一个有效的操作?(list是 的一个实例std::list)。
至少 MSVC 2019 似乎就是这种情况。
例如,这在以下情况下会很有用:
for ( auto i = list.begin(); i != list.end(); ++i )
{
...
list.erase(i--);
...
}
Run Code Online (Sandbox Code Playgroud)
,即在迭代时删除元素时,因为i可能是列表的开头。这也需要++list.end() == list.begin()持有;那个怎么样?
标准是否保证
Run Code Online (Sandbox Code Playgroud)--list.begin() == list.end()
不,标准不保证 for std::list(也不能假设给定双向迭代器)。事实上, 的行为--list.begin()是未定义的。
这也需要 ++list.end() == list.begin() 来保持;那个怎么样?
也不能保证,并且++list.end()具有未定义的行为。
[语言律师]的标准报价:
[双向.迭代器]
Run Code Online (Sandbox Code Playgroud)Expression | Operational | Assertion/note | semantics | pre-/post-condition --------------------------------------------------------- --r | | Preconditions: | | there exists s such that r == ++s. --------------------------------------------------------- r-- | { X tmp = r; | | --r; | | return tmp; } |
[输入.迭代器]
Run Code Online (Sandbox Code Playgroud)Expression | Operational | Assertion/note | semantics | pre-/post-condition --------------------------------------------------------- ++r | | Preconditions: | | r is dereferenceable.
问题是不满足先决条件。
我对写具体例子的建议。这略有不同,my_function它将在元素从列表中实际删除之前调用:
list.remove_if([](int n) {
if ( X + Y == W )
{
my_function( Y );
return X || Y && Z;
}
return true;
});
Run Code Online (Sandbox Code Playgroud)
如果需要确切的行为,那么您可以使用以下不太漂亮的方法:
for (auto it = list.begin(), last = list.end(); it != last;)
{
auto next = it;
++next;
if ( X + Y == W )
{
if ( X || Y && Z )
{
list.erase( it );
}
my_function( Y );
}
else
{
list.erase( it );
}
it = next;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |