Why is a std::move of a value from a const std::optional possible?

777 Views Asked by At

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.

  1. Why is a std::move applied to a value of a const optional legal?
  2. Why does the optional ov still hold the vector?

Does ov.value() internally create a copy to a temporary which is then moved from?

1

There are 1 best solutions below

3
Sam Varshavchik On

Why is std::move applied to a value of a const optional legal?

Sure, why not? All that std::move is, is a cast to an rvalue reference. You'll just end up with an rvalue reference to a const object. That's nothing unusual.

Why does the optional ov still holds the vector?

Because it is const, and cannot be changed.

Several conditions must happen in order for an object to be moved. std::move takes care of the most important one, but all others must be satisfied as well.

It is a common misconception that spraying std::move everywhere guarantees a super-duper-efficient move of an object from one place to another, by magic. That's not true, that's not what std::move is, 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.