1

Consider the following code snippet:

#include <iostream>

using namespace std;

struct Snitch {
  Snitch() { cout << "c'tor" << endl; }
  ~Snitch() { cout << "d'tor" << endl; }

  Snitch(const Snitch&) { cout << "copy c'tor" << endl; }

  Snitch& operator=(const Snitch&) {
    cout << "copy assignment" << endl;
    return *this;
  }

  Snitch(Snitch&&) = delete;
  Snitch& operator=(Snitch&&) = delete;
};

Snitch CreateSnitch(bool v) {
    Snitch a, b;
    if (v) {
        return a;
    }
    return b;
}

int main(int argc, char** argv)
{
    Snitch s = CreateSnitch(true);
}

This is the case when RVO doesn't work, hence move construct should be called when returning the object from the function. But as move construct is deleted I assumed copy constructor should have been called. Instead, I'm getting the following compile error in above mentioned environment:

Error C2280 'Snitch::Snitch(Snitch &&)': attempting to reference a deleted function

Also, when I'm adding const keyword both to return value type and local variables a and b it works. I suppose the latter part compiles because compiler 'understands' that there is no way to call move constructor and calls copy constructor. So, I don't understand why the initial code doesn't compile.

Mikev
  • 2,012
  • 1
  • 15
  • 27
David Hovsepyan
  • 509
  • 1
  • 3
  • 18
  • @lubgr how does it affect explicitely `delete`ing and declaring special member functions? Your comment seems somewhat irrelevant. OP seems to be asking why copy-constructor is not chosen, where it could simply substitute the deleted move-constructor. EDIT: and the duplicate question and answers address that clearly. – Fureeish Feb 28 '19 at 11:33
  • "But as move construct is deleted I assumed copy constructor should have been called." Ahh, that's the problem. You assumed incorrectly. – Eljay Feb 28 '19 at 12:39

0 Answers0