vendredi 1 février 2019

Avoiding a copy constructor call when returning the constructed object by value in C++11

I have a class without a copy constructor, which I still want to return by value. The following MCVE compiles in C++17:

class Cls {
    public:
    Cls(int x) {}
    Cls(const Cls& c) = delete;
};

Cls f(int x) {
    return Cls(x);
}

int main() {
    f(0);
}

but not in C++11:

$ g++ prog.cc -Wall -Wextra -std=c++11
prog.cc: In function 'Cls f(int)':
prog.cc:9:17: error: use of deleted function 'Cls::Cls(const Cls&)'
    9 |     return Cls(x);
      |                 ^
prog.cc:5:5: note: declared here
    5 |     Cls(const Cls& c) = delete;
      |     ^~~

As I understand it, the reason is that the compiler is allowed not to optimize the copy out, even if it should be trivial in this case.

I was hoping return std::move(Cls(x)); would work and avoid the copy constructor, but it gives the same error.

Can I fix the problem without defining the copy constructor (or the assigment operator)?

I've looked through related questions, but couldn't find a duplicate.

Aucun commentaire:

Enregistrer un commentaire