写入按值传递的函数参数是好的风格吗?

3

我常听到这样一个规则:改变函数参数的值是不好的编码风格。相反,最好创建一个被修改的副本。

但是我认为在下面这种情况下更改函数参数也是可以接受的。您认为最好的做法是什么?

Point3f GetWorldPoint(int x, int y)
{
    x = saturate(x, 0, width);
    y = saturate(y, 0, height);

    ...
}

template<typename T>
T saturate(T val, T min, T max) {
    return std::min(std::max(val, min), max);
}

我相信编译器会将其优化掉,所以这完全是个人喜好。 - Codecat
1
我认为最好的方法是我个人的看法。这使它主要基于意见。虽然显然返回值比修改引用更好。 - Barry
1
与问题无关的是,你调用的函数通常被称为 clamp。 - Mark Jansen
问题不在于引用。问题是,考虑到参数将按值传递,修改它是否是“不好的风格”?对我来说,这是一个非常奇怪的问题,但我认为专注于原始问题是很好的。 - Aaron McDaid
2
我一直听说过这个规则:改变以值传递给函数的参数是不好的编码风格。这是我的观点:这并不是不好的编码风格,完全没有问题。参数是你自己的本地副本,你可以随意处理它。 - juanchopanza
显示剩余4条评论
2个回答

2
我会把脖子伸出来说,这没问题。例如:
template<class T>
Matrix4x4<T> Transpose(Matrix4x4<T> m)
{
    return m.Transpose();
}

或者

template<class T>
Matrix4x4<T> Transpose(Matrix4x4<T> const & m)
{
    Matrix4x4<T> n(m);

    return n.Transpose();
}

哪个更加简洁?


1
在这个特定的例子中,我有些犹豫。如果我没记错的话,这两个代码之间确实存在着真正的区别。由于RVO不能应用于函数参数,第一个代码将导致转置->移动/复制,而第二个代码将导致复制->转置。这对于矩阵可能没有什么区别,但需要牢记这一点。 - kamulos
我认为,如果你要复制任何东西,通过值传递是可以的。我记得读过或听过Scott Meyers谈论这个问题,尽管我对此的回忆只有点点滴滴。 - Robinson

1

我对使用此事有一些异议

Point3f GetWorldPoint(int x, int y)
{
    x = saturate(x, 0, width);
    y = saturate(y, 0, height);

    ...
}

因为即使在语义上,饱和函数前后x和y也不相同(它们毕竟已经被饱和)。在更复杂的情况下,这可能会变得令人困惑。当然,在明显的函数中,经过饱和后,你现在使用的是饱和的x仍然很直接。
无论如何,这没有任何问题。
Point3f GetWorldPoint(int origX, int origY)
{
    int x = saturate(origX, 0, width);
    int y = saturate(origY, 0, height);

    ...
}

这样写更加清晰,优化编译器会在两种情况下创建类似的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接