简体   繁体   中英

Merging two stl containers without std::merge

I have to write a merging function that merges two stl containers without using std::merge. I wanted to use the implementation of std::merge, though.

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator merge (InputIterator1 first1, InputIterator1 last1, 
                      InputIterator2 first2, InputIterator2 last2, 
                      OutputIterator result) {
    while (true) {      
        if (first1==last1) 
            return std::copy(first2,last2,result);

        if (first2==last2) 
            return std::copy(first1,last1,result);

        *result++ = (*first2<*first1)? *first2++ : *first1++;
    }
}

I wanted to test it with this:

    std::vector<int> v1;
v1.push_back(1);
v1.push_back(7);

std::list<int> l1;
l1.push_back(23);
l1.push_back(3);

std::vector<int> v2;
std::vector<int>::iterator first1 = v1.begin(), last1 = v1.end(), output = v2.end();
std::list<int>::iterator first2 = l1.begin(), last2 = l1.end();

merge<std::vector<int>::iterator, std::list<int>::iterator, std::vector<int>::iterator>(first1, last1, first2, last2, output);

Why does this produce a run time error saying "Vector iterator not incrementable" ?

EDIT: Thanks for the answers, merging works but the output is unsorted

You need to allocate memory for v2 to make the output result iterator dereferencable.

std::vector<int> v2( v1.size() + l1.size() );

And output = v2.begin();

You're trying to write to, and beyond, v2.end() . This won't grow v2 , it will just trample over invalid memory, giving undefined behaviour.

Either make v2 large enough to write into:

std::vector<int> v2(v1.size() + l1.size());
auto output = v2.begin();

or use an insertion iterator

std::vector<int> v2;
auto output = std::back_inserter(v2);

By the way, there should be no need to specify the template arguments when calling merge ; they can be inferred from the function arguments:

merge(first1, last1, first2, last2, output);

Your code can be rewritten the following way

std::vector<int> v1;
v1.reserve( 2 );
v1.push_back(1);
v1.push_back(7);

std::list<int> l1;
l1.push_back(23);
l1.push_back(3);

std::vector<int> v2;
v2.reserve( v1.size() + l1.size() );

merge( v1.begin(), v1.end(), l1.begin(), l1.end(), std::back_inserter( v2 ) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM