Let's see what would we get if pred was a const&
std::copy_if doesn't take a const& predicate so lets implement our copy_if_const_ref
#include <vector>
#include <iostream>
/* Custom copy_if implementation using const& */
template <typename InputIt, typename OutputIt, typename UnaryPred>
OutputIt copy_if_const_ref(InputIt first, InputIt last, OutputIt d_first, const UnaryPred& pred) {
for (; first != last; ++first) {
if (pred(*first)) { /* error: no match for call to '(const main()::<lambda(int)>) (int&)' */
*d_first++ = *first;
}
}
return d_first;
}
int main() {
std::vector<int> n1 = {1, 2, 3, 4, 5, 6};
std::vector<int> n2;
int count = 0;
/* Mutable lambda that modifies a captured state because i simply want to do this */
auto pred = [=](int x) mutable {
++count;
return x % 2 == 0;
};
/* This will fail to compile because the lambda cannot modify its state */
copy_if_const_ref(n1.begin(), n1.end(), std::back_inserter(n2), pred);
return 0;
}
This code won't compile because the predicate is passed as a const UnaryPred&, which prevents the mutable lambda from modifying its captured state
A fix to this code is as simple as modifying the predicate to be
auto pred = [/* = */](int x) mutable {
/* ++count; */
return x % 2 == 0;
};
The list of the reasons for the predicate not to be a const& goes on, that was just a simple use case where my copy_if_const_ref fails.
Why would the "Standards" put limits to the flexibility of the "Standard functions" ?