Why is the following snippet legal C++ code? This is a purely theoretical question - there is no usecase that I have in mind:
#include <optional>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v{1, 2, 3};
const std::optional<std::vector<int>> ov = v;
const auto nv = std::move(ov.value());
for (const auto& x : *ov) { std::cout << x; }
for (const auto& x : nv) { std::cout << x; }
}
This yields 123123, but I do not understand the reason.
- Why is a
std::moveapplied to a value of aconst optionallegal? - Why does the
optional ovstill hold thevector?
Does ov.value() internally create a copy to a temporary which is then moved from?
Sure, why not? All that
std::moveis, is a cast to an rvalue reference. You'll just end up with an rvalue reference to aconstobject. That's nothing unusual.Because it is
const, and cannot be changed.Several conditions must happen in order for an object to be moved.
std::movetakes care of the most important one, but all others must be satisfied as well.It is a common misconception that spraying
std::moveeverywhere guarantees a super-duper-efficient move of an object from one place to another, by magic. That's not true, that's not whatstd::moveis, it's just a cast that's sometimes needed in order to move something. But that's not everything that's needed, just the most important part.