【发布时间】:2019-02-25 02:06:47
【问题描述】:
假设我有一个函数 foo(x, y, z) 是不变的 w.r.t。其论点的所有排列。我还有一个迭代器it,这样迭代器it、it + 1 和it + 2 可以被取消引用。
可以写吗
... = foo(*it++, *it++, *it++); // (1)
而不是
... = foo(*it, *(it + 1), *(it + 2)); // (2)
?
据我了解,由于(引用 cppreference.com 并考虑到 it 可以是原始指针),从 C++17 开始技术上是正确的
15) 在函数调用中,每个参数初始化的值计算和副作用相对于任何其他参数的值计算和副作用是不确定的。
未定义函数参数的求值顺序,但对于foo(),顺序无关紧要。
但这是一种可接受的编码风格吗?一方面,(1) 非常对称,暗示foo 具有这样的不变性,而(2) 看起来有些丑陋。另一方面,(1) 立即对其正确性提出质疑——阅读代码的人应检查 foo 的描述或定义以验证调用的正确性。
如果foo()的body很小,从函数定义看不变性很明显,你会接受(1)吗?
(可能这个问题是基于意见的。但我忍不住问了。)
【问题讨论】:
-
"但这是一种可接受的编码风格吗?"没有。
-
要详细说明@Barry 的评论,即使它是合法且有效的,它提出如此复杂的问题这一事实很好地表明它不应该出现在生产代码中。您希望您的代码显而易见且易于理解,这显然不是,因此这不是“可接受的编码风格”。
-
这不仅仅是因为它向阅读它的人提出了问题。这行代码在传递给 C++14 编译器时会中断,这也是一个大问题。如果代码库的其余部分不依赖于 C++17 特性,那么很容易犯这样的错误。
-
@TimRandall 在 Q 的正文中提到了 据我了解,从 C++17 开始技术上是正确的。此外,如果 Q 被标记为 C++17,则意味着它正在谈论 C++17。这就是标签系统的用途。我们不想在标题中添加标签