Presume that I am copying a std::vector
into a std::vector
with std::vector::insert
(as below).
The question is: when the vector that I am copying from is empty, are begin()
and end()
well defined in all circumstances for purposes of the std::vector::insert
call?
The reason I ask is this sentence:
If
allocator_traits::construct
is not supported with the appropriate arguments for the element constructions, or if an invalid position or range is specified, it causes undefined behavior.
https://cplusplus.com/reference/vector/vector/insert/
#include <vector>
#include <stdio.h>
void printbytes(char* bytes, size_t len) {
if(len == 0) return;
for(size_t i=0; i<len; i++)
{
printf("%x ", *(bytes+i) & 0xff);
}
printf("\n");
}
int main() {
std::vector<char> target = {'h','e','l','l','o'};
std::vector<char> source = {'w','o','r','l','d'};
//defined
target.insert(target.end(), source.begin(), source.end());
printbytes(target.data(), target.size());
//is this defined?
source.clear();
target.insert(target.end(), source.begin(), source.end());
printbytes(target.data(), target.size());
//how about this?
std::vector<char> boo;
boo.insert(boo.end(), source.begin(), source.end());
printbytes(boo.data(), boo.size());
}
Firstly, begin()
and end()
always work. We know this because std::vector
satisfies the Container requirement, and begin()
is defined as follows:
b.begin()
Result:
iterator
;const_iterator
for constantb
.
Returns: An iterator referring to the first element in the container.
Complexity: Constant.
This function has no preconditions, so it must always work, even for empty, and even for moved-from vectors.
Furthermore, all calls to insert
you're making are well-defined because the requirements for a SequenceContainer in [sequence.reqmts] (which std::vector
satisfies) require only the following for insert(p, i, j)
, where p
, i
, j
are iterators:
a.insert(p, i, j)
Result:
iterator
.
Preconditions: [Type constraints.] Neitheri
norj
are iterators intoa
.
[...]
Namely, it's not required by insert
that [i, j)
is a non-empty range.
On a side note, cplusplus.com is massively out-of-date in a lot of cases. cppreference.com is more actively maintained, though it's sometimes wrong and incomplete. When in doubt, refer directly to the C++ standard.