Search code examples
c++copy-constructorunique-ptr

Return value optimization not working for const unique_ptr member?


I have a class Whole that holds an object of a class Part via a unique_ptr. Since I do not provide a copy-constructor for Whole the copy-constructor is deleted, because of the unique_ptr member. Here is the code:

class Part {
};

class Whole {
public:
    Whole(std::unique_ptr<Part> part) : part(std::move(part)) {
    }
private:
    const std::unique_ptr<Part> part; //yields error later!
    //std::unique_ptr<Part> part; //ok!
};

I would like to create a Whole instance via a factory function called build()

Whole build() {
    auto part = std::unique_ptr<Part>{new Part{}};
    return Whole{std::move(part)};
}

which I want to use like this:

int main() {
    auto whole = build();
}

This works as long as the unique_ptr to the Part member of Whole is not declared const. As far as I understand this is due to the return value optimization which prevents the creation and copy of temporaries. However, if I declare Whole::part as const my compiler complains that the deleted copy-constructor is invoked. Why is it not possible to use the const declaration or is there a problem with this code anyway ?

I am using the GNU compiler version: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4


Solution

  • const std::unique_ptr disallow move constructor of class Whole.

    so auto whole = build(); is invalid. (even if the call would be elided, the call should be valid)

    With C++17, we have guaranteed copy elision which remove that restriction, making code correct.