0

I am trying to lean move semantics and I wrote this example. I would like to move a temporary r-value into an object on stack.

class MemoryPage
{
    public:

    size_t size;
    MemoryPage():size(0){
    }
    MemoryPage& operator= (MemoryPage&& mp_){
        std::cout << "2" <<std::endl;
        size = mp_.size;
        return *this;
    }
};
MemoryPage getMemPage()
{
    MemoryPage mp;
    mp.size = 4;
    return mp;
}
int main() {
    MemoryPage mp;
    mp = getMemPage();
    std::cout << mp.size;
    return 0;
}

I get this error at the return of getMemPage():

error: use of deleted function 'constexpr MemoryPage::MemoryPage(const MemoryPage&)'
dyp
  • 35,820
  • 10
  • 96
  • 156
Kam
  • 5,138
  • 3
  • 42
  • 84
  • 5
    The copy (and move) constructors of `MemoryPage` are implicitly defined as deleted / not declared because you provide a custom move assignment-operator. Returning an object, as in `return mp;` requires either a copy or a move constructor (even if it is not called). Make sure to follow the rule of five. – dyp Sep 22 '14 at 01:15
  • 3
    See [Rule-of-Three becomes Rule-of-Five with C++11?](http://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11) – template boy Sep 22 '14 at 01:21
  • By the way, the error message should've told you what DyP did. Not sure if you cropped it for the purposes of the question. `note: 'constexpr MemoryPage::MemoryPage(const MemoryPage&)' is implicitly declared as deleted because 'MemoryPage' declares a move constructor or move assignment operator` –  Sep 22 '14 at 03:18

1 Answers1

0

The copy constructor is:

[...] defined as deleted if any of the following conditions are true:

  • T has a user-defined move constructor or move assignment operator

In order to solve the immediate problem, you simply provide a copy constructor, i.e.:

MemoryPage(const MemoryPage&) { }

However, as noted in the comments, it's a good idea to consult Rule-of-Three becomes Rule-of-Five with C++11? . In particular, this paragraph summarizes what issues you may run into if you neglect to provide any of the special member functions:

Note that:

  • move constructor and move assignment operator won't be generated for a class that explicitly declares any of the other special member functions

  • copy constructor and copy assignment operator won't be generated for a class that explicitly declares a move constructor or move assignment operator

  • a class with a explicitly declared destructor and implicitly defined copy constructor or implicitly defined copy assignment operator is considered deprecated.

formatted for readability

Therefore it is good practice when writing a class that deals with memory management to provide all five special member functions, i.e.:

class C {
  C(const C&) = default;
  C(C&&) = default;
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  virtual ~C() { }
};
Community
  • 1
  • 1