gpt4 book ai didi

c++ - 这种递减的顺序是否调用了未定义的行为?

转载 作者:太空宇宙 更新时间:2023-11-03 10:43:07 25 4
gpt4 key购买 nike

我正在寻找确认,澄清这段代码是否定义良好。

通过将迭代器重新分配给容器的 erase() 函数的结果,在循环中删除容器的元素是很常见的。循环通常像这样有点乱:

struct peer { int i; peer(int i): i(i) {} };

int main()
{
std::list<peer> peers {0, 1, 2, 3, 4, 5, 6};

for(auto p = peers.begin(); p != peers.end();) // remember not to increment
{
if(p->i > 1 && p->i < 4)
p = peers.erase(p);
else
++p; // remember to increment
}

for(auto&& peer: peers)
std::cout << peer.i << ' ';
std::cout << '\n';
}

输出: 0 1 4 5 6

我想到以下内容可能更整洁,假设它没有调用未定义的行为:

struct peer { int i; peer(int i): i(i) {} };

int main()
{
std::list<peer> peers {0, 1, 2, 3, 4, 5, 6};

for(auto p = peers.begin(); p != peers.end(); ++p)
if(p->i > 1 && p->i < 4)
--(p = peers.erase(p)); // idiomatic decrement ???

for(auto&& peer: peers)
std::cout << peer.i << ' ';
std::cout << '\n';
}

输出: 0 1 4 5 6

我认为这行得通的原因如下:

  • peers.erase() 将始终返回递增的 p,因此再次递减它是安全的

  • peers.erase(p) 制作 p拷贝,因此它不会因排序而对错误的值进行操作reference

  • p = peers.erase(p) 返回一个 p& 因此减量操作在正确的对象上 reference .

但我有一些疑虑。我担心我通过在同一表达式中使用 --(p) 来调用错误的排序规则,其中 p 被用作参数,尽管它看起来在纸上没事。

有人能看出我的评估有问题吗?还是定义明确?

最佳答案

这取决于您用来检测要删除的元素的条件。如果您尝试删除第一个元素,它将失败,因为 erase 将返回新的 begin(),然后您将递减它。 This is illegal ,即使您立即再次递增它。

为了避免这个错误,并且因为它更常见和可读,我会坚持使用第一个版本。

关于c++ - 这种递减的顺序是否调用了未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30149060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com