gpt4 book ai didi

c++ - 调用参数置换不变函数 f(i++, i++)

转载 作者:搜寻专家 更新时间:2023-10-31 00:07:46 24 4
gpt4 key购买 nike

假设我有一个函数 foo(x, y, z) 是不变的 w.r.t.其参数的所有排列。我还有一个迭代器 it,这样迭代器 itit + 1it + 2 可以是取消引用。

这样写好不好

... = foo(*it++, *it++, *it++);  // (1)

代替

... = foo(*it, *(it + 1), *(it + 2));  // (2)

?

据我所知,从 C++17 开始技术上它是正确的(引用 cppreference.com 并考虑到 it 可以是原始指针)

15) In a function call, value computations and side effects of the initialization of every parameter are indeterminately sequenced with respect to value computations and side effects of any other parameter.

函数参数的求值顺序没有定义,但对于 foo() 来说,顺序无关紧要。

但这是一种可以接受的编码风格吗?一方面,(1) 很好地对称并且暗示 foo 具有这样的不变性,而 (2) 看起来有些难看。另一方面,(1) 立即引发对其正确性的质疑——阅读代码的人应该检查 foo 的描述或定义以验证调用的正确性.

如果 foo() 的主体很小,并且函数定义的不变性很明显,您会接受 (1) 吗?

(大概,这个问题是基于意见的。但我还是忍不住问了。)

最佳答案

你在 C++17 中是正确的

foo(*it++, *it++, *it++);

不是未定义的行为。正如您的报价所述,并如 [expr.call]/8 中所述

The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.

每个增量都是有序的,因此您不会有多个未排序的写入。函数参数的求值顺序在 C++17 中仍未指定,这意味着您只有未指定的行为(您无法知道哪个元素被传递给每个参数)。

只要你的函数不关心这个就没问题。如果参数的顺序很重要,那么您将不得不使用第二个版本。


综上所述,我更愿意使用

foo(*it, *(it + 1), *(it + 2));

即使顺序无关紧要。它使代码向后兼容,恕我直言,它更容易推理。我宁愿在 for 循环的增量部分看到 it += 3,然后在函数调用中看到多个增量,而在循环的增量部分没有增量。

关于c++ - 调用参数置换不变函数 f(i++, i++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52430588/

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