c++vectorforeachstl

C2664 Compilation Error with Nested std::for_each and Lambda Functions


std::vector<std::vector<bool>> grid(4, std::vector<bool>(4, true));
std::for_each(grid.begin(), grid.end(), [](auto& row) {
    std::for_each(row.begin(), row.end(), [](auto& free) {
        free = false;
    });
});

I want to set a true initialized 4x4 matrix to false using std::for_each. Why doesn't it compile with a C2664 error?


Solution

  • std::for_each takes its iterator parameters by value, and your lambda captures the reference to row, but not the elements inside. The innermost lambda is trying to modify bool values via auto&, but due to proxy reference issues in std::vector<bool>, it's not working as expected.

    std::vector<bool> is not a normal container of bool. It's optimized to pack bits, and its operator[] returns a proxy object, not a bool&. That proxy causes trouble with templated code like std::for_each.

    How to solve this issue?

    There is two way's to fix the mentioned issue:

    First solution:

    std::vector<std::vector<bool>> grid(4, std::vector<bool>(4, true));
    
    // Set all values to false
    for (auto& row : grid) {
        for (auto cell = row.begin(); cell != row.end(); ++cell) {
            *cell = false;
        }
    }
    

    Second solution:

    std::for_each(grid.begin(), grid.end(), [](std::vector<bool>& row) {
        for (size_t i = 0; i < row.size(); ++i) {
            row[i] = false; // Avoids the proxy reference issue
        }
    });
    

    To be frank, I recommend to avoid std::vector<bool> for mutability-critical logic. It’s a design compromise in the STL and causes more headaches than it’s worth.