c++ vector = {vec1.begin, vec1.begin} returns empty vector

142 views Asked by At

I'm trying to understand the behavior of creating a subvector of another vector.

For example, this code: https://godbolt.org/z/PYG34vnTr has a 2-element vector vec1. I want to create a vector of the first element. To get it to work, I had to use:

std::vector<int> vec2 = {vec1.begin(), vec1.begin() + 1};

I'm trying to understand why this is needed. Reason being, I'm doing a recursive loop that halves a vector in each iteration. And the formula:

std::vector<int> vec2 = {vec1.begin(), vec1.begin() + (vec1.size()-1)/2};

Works for all iterations except the one where vec1 is a 2-element vector.

What alternative code should I use?

1

There are 1 answers

0
Ted Lyngmo On BEST ANSWER

The end iterator needs to be 1 element beyond the last element you want, which means that the -1 must be removed.

Illustration:

#include <iostream>
#include <vector>

void foo(std::vector<int> inp) {
    for (auto v : inp) std::cout << ' ' << v;
    std::cout << '\n';

    if (inp.size() > 1) {
        // the midpoint:
        auto mid = inp.begin() + inp.size() / 2;

        std::cout << "L:";
        foo({inp.begin(), mid});

        std::cout << "R:";
        foo({mid, inp.end()});
    }
}

int main() {
    std::vector<int> vec1{1, 2, 3, 4};
    std::cout << "X:";
    foo(vec1);
    std::cout << "Done\n";
}

Output:

X: 1 2 3 4
L: 1 2
L: 1
R: 2
R: 3 4
L: 3
R: 4
Done

Demo


A non-copying version, working solely with iterators could look like this and gives the same result:

template<class It>
void foo(It first, It last) {
    for(auto curr = first; curr != last; ++curr) std::cout << ' ' << *curr;
    std::cout << '\n';
    auto size = std::distance(first, last);

    if (size > 1) {
        auto mid = first + size / 2;
        std::cout << "L:";
        foo(first, mid);
        std::cout << "R:";
        foo(mid, last);
    }
}

Demo