Why does the copy constructor called for the const variable with std::move

Viewed 114

I have the following piece of code running in C++14. I expect no copy constructor but there is one case that is out of my understanding. How to explain this case?

#include <iostream>
#include <vector>
 
struct Noisy {
    Noisy() { std::cout << "constructed at " << this << '\n'; }
    Noisy(const Noisy&) { std::cout << "copy-constructed\n"; }
    Noisy(Noisy&&) { std::cout << "move-constructed\n"; }
    ~Noisy() { std::cout << "destructed at " << this << '\n'; }
};
 
const std::vector<Noisy> f() {
    std::vector<Noisy> v = std::vector<Noisy>(3); // copy elision
    return v; // NRVO
}
 
void g(std::vector<Noisy> arg) {
    std::cout << "arg.size() = " << arg.size() << '\n';
}
 
int main() {
    auto v1 = f(); // OK, copy elision
    const auto v2 = f(); // OK, copy elision
    const auto& v3 = f(); // Is this legal referencing to temp variable?
    (void) v3;
    const auto v4 = v3; // OK, copy-constructed called
    const auto v5 = std::move(v2); // Why, copy-constructed called
    auto v6 = std::move(v1); // OK, no copy constructor
}
0 Answers
Related