27

I am wondering why I get an error when compiling:

const std::unique_ptr<int> get() { 
    return std::make_unique<int>(10);
}

int main() { 

    const std::unique_ptr<int> value = get();

    return EXIT_SUCCESS;
}

I get the following error:

main.cpp: In function ‘int main()’:
main.cpp:10:44: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
     const std::unique_ptr<int> value = get();

It compiles correctly when I remove const from the get signature.

Is there any way to return a constant unique_ptr ?

7
  • 2
    Is the actual std::unique_ptr object supposed to be constant, or the data pointed to by it? Commented Jul 24, 2017 at 11:46
  • 1
    @MooingDuck As a return type, this is weird. Otherwise, pimpl comes to mind as a case where a const unique_ptr to a non-const object is sometimes used. In general there's nothing weird about const pointers to non-const. If it's wrong to make the pointer point elsewhere but right to mutate the pointed-to object through the pointer, a const pointer to non-const expresses and enforces that. If one follows the somewhat common practice of making most things const except when there's a reason not to, const pointers to non-const objects arise quite often. Commented Jul 24, 2017 at 19:02
  • 1
    @EliahKagan: A const pointer in pimpl makes moves/swaps slower than they need to be, but yes, in general there are cases where a const pointer makes sense. Commented Jul 24, 2017 at 20:34
  • 1
    This is an x/y question that I dunno why it got voted so high. You state that you want the unique_ptr to be constant, despite that const return values are weird enough even before a noncopyable type like unique_ptr is added into the mix, without explaining why you thought you wanted this oddity. I don't feel that 'why can I not do [weird thing without any apparent justification]' questions are useful, otherwise I could spend my whole day inventing and posting them. Commented Jul 24, 2017 at 21:45
  • 1
    @MooingDuck There seem to be plenty of cases where const pointers are a good idea, at least if one values const-correctness. Sure, if we have full control over the function signature, a reference should be used. However, a trivial example that comes to mind where a pointer is received is a stdlib algorithm like find_if over a range in a container holding pointers (reference_wrapper doesn't seem worth the hassle & should be const itself anyway!). If the possibility were left of accidentally mutating the pointer within the receiving function, & that happens, it's not going to end well. Commented Jul 24, 2017 at 21:51

1 Answer 1

55

Because the unique_ptr is constant it can not be moved only copied. And copying a unique_ptr is not allowed (otherwise it would not be "unique").

If the data pointed to by the pointer should be constant, then use std::unique_ptr<const int> instead.

Sign up to request clarification or add additional context in comments.

6 Comments

Just a quick note: OP's example has to compile in C++17 due to guaranteed copy elision.
@bogdan Are you sure? It doesn't compile for me on clang, gcc, or msvc with -std=c++17
@bogdan The std::unique_ptr copy-constructor and copy-assignment operators are marked as delete, which means it can't be used for any kind of copying, even if the copy can be elided.
@patatahooligan Could those be older versions of the compilers? It does compile for me using reasonably recent versions of all three, Clang 5, GCC 7.3, MSVC 15.9.
@Someprogrammerdude That's true and applies in this case for anything before C++17. The rules have changed in C++17 as a result of adopting P0135. Rationale and examples are in the R0 version of the paper. Basically, initializing from a prvalue of the same type as the destination is no longer seen as a copy/move from a temporary that can be elided; it explicitly creates the destination object based on the prvalue; there isn't anything to elide anymore.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.