sorry in advance if this question is quite incomplete, unclear or a duplicate (it's my first one here). While studying move semantics and working on a small project for my OOP course I stumbled upon a question that I can't answer myself. As far as I know std::move() works by converting l-values into r values, but let's suppose we were moving a vector with a lot of elements into a second vector that has a capacity of 1. Could I use reserve() to avoid a lot of automatic memory re-allocations of the second vector or would using reserve() have no effect due to std::move() moving r-values into the second vector? A simple realization of my question can be found below.
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> first (1000000);
std::vector<int> second (1);
std::fill(first.begin(),first.end(),7);
second.reserve(1000000);//is this needed??
second=std::move(first);
return 0;
}
No, that is not needed, and is almost certainly premature optimization.
A vector really can be represented by 3 pointers (or two pointers and an offset, or one pointer and two offsets... but those aren't so common, so for the rest of my explanation I'll imagine vectors are represented by three pointers).
A move constructor std::vector<int> a = std::move(b);
could be implemented by just taking those three pointers from b
, setting them to some easy-to-make value (nullptr
as a sentinel value meaning "I'm empty", for example) and then everything would be done.
In fact, this is how gcc
does it (and most standard library implementations... but I had the gcc
source handy). See here.
So your reserve
call is at best optimized by the compiler into a no-op, and at worst, is causing an unnecessary memory allocation. No good!