“谓词不应由于函数调用而修改其状态”是什么意思?

son*_*pta 13 c++ stl predicate c++11

我在网上阅读有关C ++的内容,并遇到了以下说法:

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

我不明白“状态”在这里是什么意思。有人可以举例说明吗?

for*_*818 17

Let's consider the algorithm std::count_if as an example. It traverses a range and counts how often a given predicate evaluates to true. Further assume we want to check how many elements in a container are smaller than a given number, e.g. 5 or 15.

A predicate can be many things. It just has to be callable. It can be a functor:

struct check_if_smaller {
    int x;
    bool operator()(int y) { return y < x; }
};
Run Code Online (Sandbox Code Playgroud)

You can create different instances of that predicate, e.g. these two

check_if_smaller a{5};
check_if_smaller b{15};
Run Code Online (Sandbox Code Playgroud)

can be used to check if numbers are smaller than 5 or 15 respectively:

bool test1 = a(3);  // true because 3 < 5
bool test2 = b(20); // false because 20 is not < 15
Run Code Online (Sandbox Code Playgroud)

The member x is the state of the predicate. Typically this should not change when the predicate is applied (by calling its operator()).

From wikipedia:

In mathematical logic, a predicate is commonly understood to be a Boolean-valued function P: X? {true, false}, called the predicate on X. However, predicates have many different uses and interpretations in mathematics and logic, and their precise definition, meaning and use will vary from theory to theory.

Sloppy speaking, a predicate is a function mapping something to a boolean. The fact that we use a functor that is not just a function but a function object with a state can be considered as an implementation detail, and repeatedtly evaluating the same predicate for same input is commonly expected to yield the same result. Also, algorithms make this assumption and nothing really prevents them from copying the predicate you pass. If evaluating the predicate would alter its internal state, the algorithm may not work as expected.


Ser*_*eyA 11

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

The reason to avoid this is the fact that algorithms are under no obligation to keep a single instance of a predicate. They might easily be copied around, and state changed in one copy, will not be shared with a state in another copy. As a result, program will behave unexpectedly (for someone expecting the state change to be in effect).