c++thread-safetycondition-variable

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


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?


Solution

  • 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.)