在C ++中,可以声明一个函数为const,据我所知,这意味着编译器确保该函数不会修改该对象。在C ++中,我可以要求函数是纯函数吗?如果不是使用C ++,是否有一种语言可以满足这一要求?
如果这不可能,为什么为什么可以要求函数为const但不要求它们为纯函数呢?这些要求有何不同?
为清楚起见,我只希望没有副作用,除了传递给函数的变量外,不要使用其他变量。因此,不应读取文件或进行系统调用等。
以下是对副作用的更清晰定义:
在运行该程序的计算机上没有对文件的修改,也没有对功能范围之外的变量进行修改。除了传递给函数的变量外,没有其他信息可用于计算函数。每次运行该函数都应返回相同的内容。
注意:我进行了更多研究,并遇到了pure script (感谢jarod42的评论)
基于对Wikipedia文章的快速阅读,我给您的印象是您可以要求函数必须使用纯脚本纯净,但是我不确定。
答案 0 :(得分:1)
当前,C ++没有一种机制来确保函数“没有副作用,除了传递给函数的变量外,没有使用任何变量”。如Jack Bashford所述,您只能强迫自己编写纯函数。编译器无法为您进行检查。
有一个提案(N3744提案[[pure]]
)。在这里,您可以看到GCC和Clang已经支持__attribute__((pure))
。也许它将在将来的C ++版本中以某种形式进行标准化。
答案 1 :(得分:0)
简短的回答:否。没有pure
这样的等效关键字约束const
一样的功能。
但是,如果您要保留一个特定的全局变量,则可以选择static type myVar
。这将要求只有该文件中的函数才能使用它,而该文件之外的任何东西都不能使用。这意味着该文件外部的任何功能都将受到约束而无法保留。
关于“副作用”,我将分解每个副作用,以便您知道有哪些选择:
您不能约束某个函数来执行此操作。 C ++只是没有提供约束这样的函数的方法。但是,您可以根据需要设计一个不修改任何文件的功能。
除了指针或引用作为参数传递的任何内容外,全局变量是您可以在函数范围之外修改的唯一变量。全局变量可以选择为常量或静态变量,这将使您无法修改它们,但是除此之外,我知道您真的无能为力。
同样,您知道我不能限制它这样做。但是,您可以根据需要将功能设计为像这样工作。
我不确定我为什么要限制这样的功能,但是不知道。并不是我知道。同样,如果您愿意,也可以这样设计。
为什么C ++不提供这样的选项?我正在猜测可重用性。似乎您有一个特定的列表,这些列表是您不希望函数执行的操作。但是,作为一个整体,许多其他C ++用户将需要此特定约束集的可能性通常很小。也许他们一次只需要一两个,但不是一次全部需要。添加它似乎并不值得麻烦。
但是,关于const
不能说相同。 const
一直使用,尤其是在参数列表中。如果通过引用或其他方式传递数据,这将防止数据被修改。因此,编译器需要知道哪些函数会修改对象。它在函数声明中使用const
进行跟踪。否则,它将无法得知。但是,使用const
非常简单。它可以限制对象只使用保证其保持不变的函数,或者在函数中的声明中使用const
关键字。
因此,const
得到了很多重用。
答案 2 :(得分:0)
在C ++中,可以声明一个函数为const,据我所知,这意味着编译器确保该函数不会修改该对象。
不完全是。编译器将允许使用const_cast
来修改对象(可能不建议使用)。因此,编译器仅确保函数不会意外修改对象。
是什么使这些要求(恒定和纯粹)不同?
它们是不同的,因为一个影响正确的功能,而另一个不影响正确的功能。
假设C
是一个容器,并且您要遍历其内容。在循环内的某个时刻,也许您需要调用一个以C
作为参数的函数。如果该功能用于clear()
容器,则循环可能会崩溃。当然,您可以构建一个可以处理该问题的循环,但要点是,有时呼叫者需要确保不会将地毯从其下面拉出。因此,可以标记事物const
。如果将C
作为对函数的常量引用进行传递,则该函数有望不修改C
。该承诺提供了必要的保证(即使如上所述,该承诺也可能被破坏)。
我不知道使用非纯函数会类似地导致程序崩溃的情况。如果没有用处,为什么还要使语言复杂化?如果您能提出一个很好的用例,则可能是将来对该语言进行修订的考虑因素。
(知道函数是纯函数可以帮助编译器优化代码。据我所知,它由每个编译器来定义如何标记它,因为它不会影响功能。)