You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中v != std::exchange(v, pmap[v])的求值顺序是否有标准保证?

关于std::exchange与operator!=求值顺序的疑问

我发现越来越多适合使用std::exchange的编程写法。今日我在回答中写出了如下代码:

do {
    path.push_front(v);
} while (v != std::exchange(v, pmap[v]));

相比如下写法,我更喜欢上面的版本:

do {
    path.push_front(v);
    if (v == pmap[v])
        break;
    v= pmap[v];
} while (true);

原因想必不言而喻。但我不太熟悉标准术语,不禁担心lhs != rhs不能保证左操作数先于右操作数求值,这会导致比较恒为true。不过实际代码运行正常,似乎是先求值左操作数。

请问:

  1. C++标准是否保证该求值顺序?
  2. 若该规则在近年标准中有变化,首个规定此内容的标准版本是哪个?

注:我意识到这是f(a,b)(其中f为operator!=)的特殊情况,我已尝试查阅相关资料但尚未得出结论。


问题1解答

C++标准保证operator!=的左操作数会先于右操作数求值。对于内置的比较运算符(包括!=),左操作数属于顺序点前的求值项,必须在右操作数计算完成前完成求值。也就是说,v != std::exchange(v, pmap[v])中会先获取左边v的原始值,再执行右边的std::exchange(此时修改v的值),比较的是修改前的v和pmap[v]的值,逻辑完全正确。

问题2解答

这个求值顺序规则是在C++17中首次被明确标准化的。在C17之前,除了&&、||和逗号运算符这类原本就有顺序保证的运算符外,大多数二元运算符(包括!=)的左右操作数求值顺序是未指定的,编译器可自由选择求值顺序。但从C17开始,所有内置二元运算符都被规定为左操作数先求值,再处理右操作数。因此你的代码在C17及以后版本中行为确定,而在C17之前,这段代码的行为属于未定义(尽管很多编译器可能按左先右后的顺序实现,但标准不做强制保证)。


内容的提问来源于stack exchange,提问作者sehe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:50:37