简体   繁体   中英

c++ std::vector iterator constructor with first == last

I have a function which needs to divide a vector up into n sub-vectors. For example, it might look something like this:

void foo(std::vector<uint8_t> vec, int numSubVectors){
    size_t size = vec.size() / numSubVectors;
    auto iter = vec.begin();
    for (int i = 0; i < numSubVectors; ++i) {
        auto sub_vec = std::vector<uint8_t>(iter, iter + size);
        // do something with sub_vec
        // ...

        iter += size;
    }
}

I need this to work when called with foo({}, 1) , where sub_vec gets assigned an empty vector on the first (and only) iteration of the loop. I'm concerned about the std::vector<uint8_t>(iter, iter + size) . Does the c++ standard allow a vector to be constructed using its range constructor when first == last?

According to cplusplus.com , "The range used is [first,last), which includes all the elements between first and last, including the element pointed by first but not the element pointed by last", but that statement doesn't make any sense when first == last?

I tried running it on an online IDE and it seems to work ( https://ideone.com/V9hylA ), so it's clearly not prohibited, but is it undefined behaviour?

From iterator.requirements.general of the standard:

An iterator and a sentinel denoting a range are comparable. A range [i, s) is empty if i == s; otherwise [...]

So when first == last, the standard explicitly defines this as an empty range.

The iterator pair [first, last) where first == last is how we define an empty range. It's syntactically and logically valid. Constructing a std::vector from that iterator pair will do the correct thing and create an empty container.

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