在Alexander A. Stepanov和Paul McJones的“编程元素”一书中指出:
功能程序的规律性允许两种传递输入的技术。当参数的大小很小或者程序需要副本时它可以变异,我们按值传递它,制作本地副本。否则我们通过常量引用传递它。
使用本书中的以下定义
当且仅当用相等对象替换其输入时,过程才是规则的,导致输出对象相等。
假设存在一个对象类型,它表示单个单词中的布尔值,我们称之为foolean。 0被解释为假,所有其他状态(1 ... n)被解释为真。
现在让我们假设存在一个采用foolean值的过程,并将其表示形式返回为0和1的字符串。
这个过程显然不是常规的,因为可以传递许多真值,它会返回不同的输出对象。但是我没有看到如何通过值或常量引用传递它是有问题的(除了这样的数据类型开始时是不明智的事实!)。
与允许这两种技术的其他程序相比,功能程序的规律性是什么?
常规类型的一个属性是:
auto a = b;
assert(a==b);
持有;副本是平等的。你可能有一个没有这个属性的不规则类型;例如,==
可能会检查身份,而副本可能会创建一个单独的身份。
在常规程序中,我们有如果(a==b)
,那么f(a)
和f(b)
具有相同效果的属性。
但f( X const& )
不做副本,而f( X )
确实做了副本。因此,如果类型X
是不规则的,因为副本不相等,那么将f( X const& )
转换为f( X )
可以改变行为。
现在你不需要完全保持规则,但是这个属性是由函数和类型的规律性所暗示的。
我觉得有重要的部分:
功能程序的规律性允许两种传递输入的技术。当参数的大小很小或者程序需要副本时它可以变异,我们按值传递它,制作本地副本。否则我们通过常量引用传递它。
对于C ++中的任何函数来说,这实际上是一种很好的做法。
按值传递对象会在内存中创建一个副本,所以如果对象很大并且你真的不需要一个可变副本,那么你真的不想这样做,那就是当你通过引用传递它时(它不会创建一个副本) )。请注意,您应该总是更喜欢传递const
引用,除非您确实需要一个可变引用(您不应该)。
常规功能仅向您保证,在创建副本时,您不会更改行为。
此外,您在那里描述的功能(使用foolean
)是常规的。规律性并不意味着没有两个输入可以产生相同的输出。 f(1) == f(2)
并不意味着f
不是常规的,只要f(1)
仍然与f(copy(1))
相同(有时它不是)。