简体   繁体   中英

What does std::vector::insert does, if it is fed by reverse iterator?

I am populating vector keeping it ordered in the following manner

vector<int>::iterator it = upper_bound(arr.begin(), arr.end(), value);
arr.insert(it, value);

Now I would like to keep reversed order. What if I do

vector<int>::iterator it = upper_bound(arr.rbegin(), arr.rend(), value).base();
arr.insert(it, value);

will

arr.insert(it, value);

work correctly, ie put new value AFTER found entry in arr ?

What is with complexity? How long will it take to insert element in the beginning of iteration, ie in the end of vector? Close to O(1) right?


I tried this

vector<int> src = {10, 1, 3, 7, 2, 100};
    vector<int> dst;

    for (auto it=src.begin(); it!=src.end(); ++it) {
        //auto it2 = upper_bound(dst.begin(), dst.end(), *it);
        vector<int>::iterator it2 = upper_bound(dst.rbegin(), dst.rend(), *it).base();
        dst.insert(it2, *it);
    }

and it worked, but why? If it2 is normal iterator, then, for example when searching for 7 in {10, 1, 3 it2 will point to 10 and insert will insert 7 BEFORE 10 .

How it appears after?


The following code

int main() {

    vector<int> src = {10, 1, 3, 7, 2, 100};
    vector<int> dst;

    auto begin = src.begin();

    for (auto it=src.begin(); it!=src.end(); ++it) {
        cout << *it << endl;

        //auto it2 = upper_bound(dst.begin(), dst.end(), *it);
        vector<int>::iterator it2 = upper_bound(dst.rbegin(), dst.rend(), *it).base();
        if (it2 == begin) {
            cout << "begin" << endl;
        }
        dst.insert(it2, *it);
    }

    cout << dst << endl;

}

prints

10
1
3
7
2
100
100, 10, 7, 3, 2, 1

ie it never prints "begin". But why?

If it2 is normal iterator, then, for example when searching for 7 in {10, 3, 1} it2 will point to 10 and insert will insert 7 BEFORE 10.

Except that a reverse iterator dereferences to the value next to it's base (following from the pov of the base type, preceding from the pov of the reverse). You can observe this by dereferencing it2 (as long as it precedes dst.end() ), it points to 3 in that case.

Here's more intermediate output, showing the difference

int main() {

    std::vector<int> src = {10, 1, 3, 7, 2, 100};
    std::vector<int> dst;

    for (int i : src) {
        std::cout << i << " ";
        auto it = upper_bound(dst.rbegin(), dst.rend(), i);
        auto it2 = it.base();
        if (it != dst.rend()) {
            std::cout << *it << " ";
        } else {
            std::cout << "first ";
        }
        if (it2 != dst.end()) {
            std::cout << *it2;
        } else {
            std::cout << "last";
        }
        std::cout << std::endl;
        dst.insert(it2, i);
    }

    std::cout << dst << std::endl;

}

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