为什么功能过程的规律性允许按值传递和按常量引用传递?
Why does the regularity of functional procedures allow passing by value & passing by constant reference?
在 Alexander A. Stepanov 和 Paul McJones 的编程基础一书中指出:
The regularity of functional procedures allows two techniques for passing inputs. When the size of the parameter is small or if the procedure needs a copy it can mutate, we pass it by value, making a local copy. Otherwise we pass it by constant reference.
使用书中的以下定义
A procedure is regular if and only if replacing its inputs with equal objects results in equal output objects.
假设存在一个对象类型,用一个词表示布尔值,我们称它为foolean。 0 被解释为假,所有其他状态 (1...n) 被解释为真。
现在让我们假设存在一个过程,它采用一个 foolean 值,return将其表示为零和一的字符串。
这个过程显然不规则,因为可以向它传递许多真值,并且它会 return 不同的输出对象。但是,我看不出按值或常量引用将输入传递给它会有什么问题(除了这样的数据类型一开始是不明智的!)。
与允许这两种技术的其他程序相比,功能程序的规律性如何?
一个属性常规类型是:
auto a = b;
assert(a==b);
成立;份数相等。你可以有一个 没有 的不规则类型 属性;例如,==
可能会检查身份,而副本可能会创建一个单独的身份。
在常规程序中,我们有 属性 如果 (a==b)
,则 f(a)
和 f(b)
具有相同的效果。
但是f( X const& )
不复制,而f( X )
复制。因此,如果类型 X
不规则,因为副本不相等,则将 f( X const& )
转换为 f( X )
可以改变行为。
现在你不需要完全的规律性来保持这个,但是这个 属性 是由函数和类型的规律性暗示的。
我觉得重要的是:
The regularity of functional procedures allows two techniques for passing inputs. When the size of the parameter is small or if the procedure needs a copy it can mutate, we pass it by value, making a local copy. Otherwise we pass it by constant reference.
对于 C++ 中的任何函数,这实际上都是一个很好的做法。
按值传递对象会在内存中创建一个副本,因此如果对象很大并且您真的不需要可变副本,您真的不想这样做,那是您通过引用传递它的时候(不会创建副本)。请注意,除非您确实需要可变引用(您不应该这样做),否则您应该始终更喜欢传递 const
引用。
常规函数只是向您保证,当您创建一个副本时,您不会改变行为。
此外,您在那里描述的函数(带有 foolean
) 是 常规函数。规律性并不意味着没有两个输入可以产生相同的输出。 f(1) == f(2)
并不意味着 f
不规则,只要 f(1)
仍然与 f(copy(1))
相同(有时不是)。
在 Alexander A. Stepanov 和 Paul McJones 的编程基础一书中指出:
The regularity of functional procedures allows two techniques for passing inputs. When the size of the parameter is small or if the procedure needs a copy it can mutate, we pass it by value, making a local copy. Otherwise we pass it by constant reference.
使用书中的以下定义
A procedure is regular if and only if replacing its inputs with equal objects results in equal output objects.
假设存在一个对象类型,用一个词表示布尔值,我们称它为foolean。 0 被解释为假,所有其他状态 (1...n) 被解释为真。
现在让我们假设存在一个过程,它采用一个 foolean 值,return将其表示为零和一的字符串。
这个过程显然不规则,因为可以向它传递许多真值,并且它会 return 不同的输出对象。但是,我看不出按值或常量引用将输入传递给它会有什么问题(除了这样的数据类型一开始是不明智的!)。
与允许这两种技术的其他程序相比,功能程序的规律性如何?
一个属性常规类型是:
auto a = b;
assert(a==b);
成立;份数相等。你可以有一个 没有 的不规则类型 属性;例如,==
可能会检查身份,而副本可能会创建一个单独的身份。
在常规程序中,我们有 属性 如果 (a==b)
,则 f(a)
和 f(b)
具有相同的效果。
但是f( X const& )
不复制,而f( X )
复制。因此,如果类型 X
不规则,因为副本不相等,则将 f( X const& )
转换为 f( X )
可以改变行为。
现在你不需要完全的规律性来保持这个,但是这个 属性 是由函数和类型的规律性暗示的。
我觉得重要的是:
The regularity of functional procedures allows two techniques for passing inputs. When the size of the parameter is small or if the procedure needs a copy it can mutate, we pass it by value, making a local copy. Otherwise we pass it by constant reference.
对于 C++ 中的任何函数,这实际上都是一个很好的做法。
按值传递对象会在内存中创建一个副本,因此如果对象很大并且您真的不需要可变副本,您真的不想这样做,那是您通过引用传递它的时候(不会创建副本)。请注意,除非您确实需要可变引用(您不应该这样做),否则您应该始终更喜欢传递 const
引用。
常规函数只是向您保证,当您创建一个副本时,您不会改变行为。
此外,您在那里描述的函数(带有 foolean
) 是 常规函数。规律性并不意味着没有两个输入可以产生相同的输出。 f(1) == f(2)
并不意味着 f
不规则,只要 f(1)
仍然与 f(copy(1))
相同(有时不是)。