You may want to consider the idiom of passing the container by x-value reference and then returning a copy/moved version.
This gives the advantages of efficiency coupled with readability at the call site.
An extended example below.
Note that all the 'apparent' copying of the vector will be elided (optimised away) by the compiler (RVO).
Also note that because Container&& is evaluated in deduced context, it will automatically be either a const Container& or a Container&&, whichever is most appropriate in the context of the call site. This means the same function can be used to both mutate an existing container (x = sorted(x)) or to make a mutated copy (x = sorted(y))
#include <iostream> #include <vector> #include <algorithm> template<class Container, class Predicate> auto all_except(Container&& c, Predicate&& pred) { auto result = std::forward<Container>(c); result.erase(std::remove_if(std::begin(result), std::end(result), std::forward<Predicate>(pred)), std::end(result)); return result; } template<class Container> auto sorted(Container&& c) { auto result = std::forward<Container>(c); std::sort(std::begin(result), std::end(result)); return result; } auto even_items = [](auto const& item) { return item % 2 == 0; }; auto odd_items = [](auto const& item) { return item % 2 != 0; }; template<class Vec> void emit(const Vec& v) { std::cout << "["; auto sep = " "; for (auto const& e : v) { std::cout << sep << e; sep = ", "; } std::cout << " ]" << std::endl; } int main() { std::vector<int> vec = {65, 2, 32, 63, 9, 13, 88, 22, 4, 5, 6, 7}; emit(all_except(vec, even_items)); emit(all_except(vec, odd_items)); emit(all_except(sorted(vec), odd_items)); vec = sorted(all_except(std::move(vec), even_items)); emit(vec); return 0; }
expected results:
[ 65, 63, 9, 13, 5, 7 ] [ 2, 32, 88, 22, 4, 6 ] [ 2, 4, 6, 22, 32, 88 ] [ 5, 7, 9, 13, 63, 65 ]
vectoritself. The pattern of the standard algorithmstd::remove_ifis to move the elements to the end, then you can erase them afterwards.vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](int i){return !(i%2);}), std::end(vec));