template<class InputIt, class OutputIt, class UnaryPred>
OutputIt copy_if(InputIt first, InputIt last,
OutputIt d_first, UnaryPred pred)
{
for (; first != last; ++first)
if (pred(*first))
{
*d_first = *first;
++d_first;
}
return d_first;
}
Above is the sample implementation from cppreference for copy_if. My question is why the 3rd parameter is not a const reference?
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;
};
So if std::copy_if
was behaving just like copy_if_const_ref
, I would have to edit my predicate to use it. And if I have to maintain a state and update it, I wouldn't be able to use std::copy_if
and I would have to implement my own.
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"?