Good points.

1. I'm not sure what the difference is between forward iterators and input iterators.
Isn't forward iterator the most generic iterator ? I'll have to refresh my c++ knowledge.

2. Yes, it did feel wrong using a container. Using a container is less general too. Now when i think about it, i should have gone for the more general way.

2 and 3: At the time i was thinking that the programmer would usually alloc up a new container with the needed size anyway so why not do it in the function. But yes it does limit its usability.

4. What do you mean ? 
move_if reuses the input iterator which results in more efficiency then partition_copy.
I based move_if on how remove_if works.


Here's version 2 - how move_if should have been in the first place

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

using namespace std;

template <typename InputIt, typename OutIt, typename Predicate>
inline InputIt move_if(InputIt first, InputIt last, OutIt out, Predicate pred)
{
    if (first == last)
        return last; // Empty so nothing to move
    InputIt new_end = first;
    for (auto i = first; i != last; ++i)
    {
        if (pred(*i)) // Should it move it ?
            *out++ = move(*i);
        else
            *new_end++ = move(*i);
    }
    return new_end;
}

int main()
{
    vector<int> v(10);
    generate(v.begin(), v.end(), [] () -> int {
        static size_t i = 1;
        return i++ * 11;
    });

    auto is_prime = [](int i){return (i % 2)==0;};
    const size_t size = count_if(v.cbegin(), v.cend(), is_prime);
    vector<int> n(size);
    auto new_end = move_if(v.begin(), v.end(), n.begin(), is_prime);
    v.erase(new_end, v.end());

    auto print_vec_int = [](vector<int> v) {
        cout << "[" << v.size() << "]";
        for_each(v.cbegin(), v.cend(), [](const int &i) {
            cout << " " << i;
        });
        cout << endl;

    };

    print_vec_int(v);
    print_vec_int(n);
}

/* Output:
[5] 11 33 55 77 99
[5] 22 44 66 88 110
*/

 

Your suggestion of using make_move_iterator() with copy_if() while the moving works it doesn't fix up the input container.

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main()
{
    vector<int> v(10);
    generate(v.begin(), v.end(), [] () -> int {
        static size_t i = 1;
        return i++ * 11;
    });

    auto is_prime = [](int i){return (i % 2)==0;};
    const size_t size = count_if(v.cbegin(), v.cend(), is_prime);
    vector<int> n(size);
    copy_if(make_move_iterator(v.begin()), make_move_iterator(v.end()), n.begin(), is_prime);

    auto print_vec_int = [](vector<int> v) {
        cout << "[" << v.size() << "]";
        for_each(v.cbegin(), v.cend(), [](const int &i) {
            cout << " " << i;
        });
        cout << endl;

    };

    print_vec_int(v);
    print_vec_int(n);
}

/* Output:
[10] 11 22 33 44 55 66 77 88 99 110
[5] 22 44 66 88 110
*/
 

Using your example code (slightly modified):

#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main()
{
    vector<string> dst;

    {
        vector<string> src;

        src.push_back("The Motion Picture");
        src.push_back("The Wrath Of Khan");
        src.push_back("The Search For Spock");
        src.push_back("The Voyage Home");
        src.push_back("The Final Frontier");
        src.push_back("The Undiscovered Country");
        src.push_back("Generations");
        src.push_back("First Contact");
        src.push_back("Insurrection");
        src.push_back("Nemesis");
        src.push_back("Star Trek");

        copy_if(
            make_move_iterator(src.begin()),
            make_move_iterator(src.end()),
            back_inserter(dst),
            [](const string& s) {
                return s != "The Final Frontier";
        });

        for (auto i = src.begin(); i != src.end(); ++i) {
            cout << "\"" << *i << "\""<< endl;
        }
    }

    cout << endl;

    for (auto i = dst.begin(); i != dst.end(); ++i) {
        cout << "\"" << *i << "\""<< endl;
    }
}

/* Output:
""
""
""
""
"The Final Frontier"
""
""
""
""
""
""

"The Motion Picture"
"The Wrath Of Khan"
"The Search For Spock"
"The Voyage Home"
"The Undiscovered Country"
"Generations"
"First Contact"
"Insurrection"
"Nemesis"
"Star Trek"

*/