Having this code:
template <class IIt, class OIt> OIt copy2(IIt begin, IIt end, OIt dest) { while (begin != end) { //make gap between element addresses for (int i = 0; i < 99999999; i++) { dest++; } *dest++ = *begin++; } return dest; } int main(int argc, char** argv) { vector<int> vec({ 1, 2, 3 }); vector<int> vec2; copy2(vec.begin(), vec.end(), back_inserter(vec2)); for (int i : vec2) { cout << i << endl; } }
Which takes quite a long to compile, but will finally do with the proper output
1 2 3
The problem is (without knowing the inner implementation of std::vector
, is it c-style
array? or more complex structure?), how can it properly find those elements in the for(int i:vec2)
, when the address (pointers) of those elements are not sequential? (i.e. because of the shifting of the iterator/pointer by 99999999
).
I thought there was a requirement for OutputIterator
to have that property, that only one-access, one-shift could be performed on it. But when you shift(add) it more than once between accessing them, then there is a gap, which is quite huge in my case. So how does it compile?
Element access:reference operator [g] – Returns a reference to the element at position 'g' in the vector. at(g) – Returns a reference to the element at position 'g' in the vector. front() – Returns a reference to the first element in the vector. back() – Returns a reference to the last element in the vector.
1) std::vector is a sequence container that encapsulates dynamic size arrays. 2) std::pmr::vector is an alias template that uses a polymorphic allocator. The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements.
You've been fooled.
The iterator returned by std::back_inserter
has it++
as a no-op. So those 'gaps' you are creating? Yeah that's all doing nothing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With