What does `std::move` on a predicate lambda mean?

73 views Asked by At

I am reading through https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for and there is the line:

return wait_until(lock, std::chrono::steady_clock::now() + rel_time, std::move(stop_waiting));

How is the std::move to be understood, or rather, what does it protect against?

On a second note, the page says the return wait_until(.. is equivalent to wait_for. Really with the return? Or did they mean a simple, direct equivalence of both functions, implicitly referring to the absolute timepoint they create within the param list?

1

There are 1 answers

3
chi On BEST ANSWER

The predicate could be an object which is expensive to copy. Here's an example:

std::vector<std::string> v(1'000'000); // A large vector

... // Fill the vector with actual data

// The vector is then moved inside the predicate closure object.
// This avoids the copy of the vector.
auto predicate = [v = std::move(v)](std::string s) -> bool {
    return s == v[2];
};

// Pass the predicate by move, so that the vector is not copied.
some_predicate_using_function(std::move(predicate));

Now, if some_predicate_using_function makes a copy of its predicate argument, the vector is then copied which is inefficient. Using std::move once again prevents that copy.

Moreover, the closure could even not support copies at all, e.g., when it captures a type that can not be copied like a unique_ptr.

For these reasons functions using predicate objects should attempt at avoiding copies when possible. (This is also true in general: template functions dealing with unknown, potentially large or non-copyable objects should avoid copies.)