lundi 5 décembre 2016

just add destructor that do nothing can cause compile error (around std::move), why?

While I was learning std::move, I found a strange issue.

If I add only a destructor that do nothing to a perfect program, I will get a compile error.

#include <iostream>
using namespace std;
class M{
    public: int database=0;
    M& operator=(M&& other){
        this->database=other.database;
        other.database=0;
        return *this;

    }
    M(M &&other) {
        *this = std::move(other);
    }
    M (M& m)=default;
    M ()=default;
    ~M() { /* free db */ }
};

class B{ 
    public: M shouldMove;
    //~B(){}   //<---  ## Adding this line will cause compile error. ##
};

int main() {
    B b;
    B b2=std::move(b); //## error at this line if the above line is added
    return 0;
}

Live code: http://ift.tt/2ha4HnM

The error is invalid initialization of non-const reference of type 'B&' from an rvalue of type 'std::remove_reference<B&>::type {aka B}'.

Question:

  • Which rules of C++ syntax enforce that? In other words, what does the error mean?
  • If I want to add destructor that do almost nothing (e.g. only print debug log) to B, do I really have to follow the rule-of-five instead?

I think the rule of zero is just a good practice.

However, from this example, it seems to me that it is a hard rule that if violated, I will get compile error.

Aucun commentaire:

Enregistrer un commentaire