“这是什么意思?”;谓词不应由于函数调用而修改其状态;? 我在网上阅读C++,遇到了这样的语句:

“这是什么意思?”;谓词不应由于函数调用而修改其状态;? 我在网上阅读C++,遇到了这样的语句:,c++,c++11,stl,predicate,C++,C++11,Stl,Predicate,谓词不应由于函数调用而修改其状态 我不明白这里“国家”是什么意思。有人能举例说明吗?用外行术语来说,谓词中的状态是数据成员。谓词更改状态意味着成员get在算法执行期间发生了更改,并且该更改将影响谓词行为 避免这种情况的原因是,算法没有义务保留谓词的单个实例。它们可能很容易被复制,并且在一个副本中更改的状态不会与另一个副本中的状态共享。因此,程序将出乎意料地发生(对于预期状态改变的人)。它遍历一个范围并统计给定谓词计算为true的频率。进一步假设我们要检查容器中有多少元素小于给定的数字,例如5或1

谓词不应由于函数调用而修改其状态

我不明白这里“国家”是什么意思。有人能举例说明吗?

用外行术语来说,谓词中的状态是数据成员。谓词更改状态意味着成员get在算法执行期间发生了更改,并且该更改将影响谓词行为


避免这种情况的原因是,算法没有义务保留谓词的单个实例。它们可能很容易被复制,并且在一个副本中更改的状态不会与另一个副本中的状态共享。因此,程序将出乎意料地发生(对于预期状态改变的人)。它遍历一个范围并统计给定谓词计算为true的频率。进一步假设我们要检查容器中有多少元素小于给定的数字,例如5或15

谓词可以是许多事物。它必须是可调用的。它可以是一个函子:

struct check_if_smaller {
    int x;
    bool operator()(int y) const { return y < x; }
};
可用于检查数字是否分别小于
5
15

bool test1 = a(3);  // true because 3 < 5
bool test2 = b(20); // false because 20 is not < 15
booltest1=a(3);//正确,因为3小于5
布尔测试2=b(20);//错误,因为20不小于15
成员
x
是谓词的状态。通常,在应用谓词时(通过调用其
运算符()
),这一点不应改变

发件人:

在数理逻辑中,谓词通常被理解为 布尔值函数P:X→ {true,false},调用上的谓词 然而,谓词在语言中有许多不同的用法和解释 数学和逻辑,以及它们的精确定义、意义和用途 不同的理论会有所不同


粗略地说,谓词是将某个对象映射到布尔值的函数。我们使用的函子不仅是一个函数,而且是一个具有状态的函数对象,这一事实可以被视为一个实现细节,对于相同的输入,重复计算相同的谓词通常会产生相同的结果。此外,算法做出了这样的假设,没有任何东西真正阻止它们复制您传递的谓词(实际上)。如果对谓词进行求值会改变其内部状态,则算法可能无法按预期工作。

基本上,标准规定谓词应该像纯函数一样工作(用数学术语),即其返回值应该仅依赖于输入

之所以提到状态,是因为谓词可以在不同的线程中复制或调用,这取决于实现和平台行为。对于lambda和其他非函数的可调用对象,这可能意味着对存储的无序访问(通过引用捕获),或者访问不同的值(如果它们是通过值捕获的)。对于函数而言,这意味着任何副作用(包括静态变量的更改)都可能导致问题


如果用于排序的谓词将为同一对返回不同的结果,则某些排序算法将无效。

除其他答案外,许多采用谓词的算法不保证任何特定的遍历顺序(ExecutionPolicy重载允许交错遍历)。对于同一个问题,你可能会得到不同的答案

如果有多个线程调用谓词,并且它更改了一些共享值,即未定义的行为

  • 或一个线程交错调用

  • 传递给函数的谓词对象可能被复制任意次数(例如递归快速排序)。如果它们的比较操作(函数调用)改变了它们的状态,那么每个谓词都会得到不同的状态。你的意思是说任何人都应该避免在谓词执行时改变x,对吗?将x设为私有并使用setX(…)方法来控制一切可以吗?@Gupta
    a
    为谓词“检查一个数字是否小于5”建模。如果更改其
    x
    成员,则它是另一个谓词。当然,您可以将
    x
    设为私有,尽管我不认为这有什么区别,或者我还建议将谓词函数调用操作符
    const
    ,如果它不修改其状态:
    bool operator()(int y)const{return y
    ,并且,这里有一个链接到标准中的相关注释:@DanielLangr真棒,我会将其编辑到答案中,只是现在没有时间
    bool test1 = a(3);  // true because 3 < 5
    bool test2 = b(20); // false because 20 is not < 15