Search code examples
c++stl-algorithm

Functional versions of C++ copy_if, transform etc


A non-iterator version of e.g. all_of can be written:

template <class Container, class UnaryPredicate>
bool all_of(Container s, UnaryPredicate f) {
  return all_of(s.begin(), s.end(), f);
}

But I don't think you can do the same with algorithms that return containers?

template <class Container, class UnaryPredicate>
Container copy_if(Container, UnaryPredicate);

The closest I got to an implementation got as far as using a vector to hold an intermediate result, but tripped over the lack of any way to supply a template parameter for the vector. Is there something I'm missing?


Solution

  • You should use std::insert_iterator instead of using a vector to hold your temporary:

    template <class Container, class UnaryPredicate>
    Container copy_if(Container const& input, UnaryPredicate const& up) {
        Container tmp;
        std::copy_if(input.begin(), input.end(),
                     std::insert_iterator<Container>(tmp, tmp.begin()), up);
        return tmp;
    }
    

    std::insert_iterator needs your container to have an insert() method, which is a not a requirement of Container but a requirement of both SequenceContainer and AssociativeContainer (table is not complete, but [associative.reqmts] requires it (Table 102)).


    If you really want to use a vector and all your Container respect the Container concept, then you can access their value type using:

    typename Container::value_type
    

    E.g.:

    std::vector<typename Container::value_type>