2

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
}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Jannus YU
  • 89
  • 6
  • I'm not finished analysing, but, you should log the assignment operators too. – Ted Lyngmo Apr 10 '21 at 01:09
  • 5
    `v2` is `const`. You can't move from a `const` object. A move constructor would try to change the passed instance. – François Andrieux Apr 10 '21 at 01:12
  • 2
    Regarding `// Is this legal referencing to temp variable?` see [Does a const reference class member prolong the life of a temporary?](https://stackoverflow.com/questions/2784262/does-a-const-reference-class-member-prolong-the-life-of-a-temporary). – François Andrieux Apr 10 '21 at 01:13
  • When would returning a const value be more useful than returning a non-const one? – Lingxi Apr 10 '21 at 03:17

0 Answers0