5

As per N3797, std::make_unique has three "overloads":

20.8.1.4 unique_ptr creation [unique.ptr.create]

template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);

1 Remarks: This function shall not participate in overload resolution unless T is not an array.

2 Returns: unique_ptr<T>(new T(std::forward<Args>(args)...)).

template <class T> unique_ptr<T> make_unique(size_t n);

3 Remarks: This function shall not participate in overload resolution unless T is an array of unknown bound.

4 Returns: unique_ptr<T>(new remove_extent_t<T>[n]()).

template <class T, class... Args> unspecified make_unique(Args&&...) = delete;

5 Remarks: This function shall not participate in overload resolution unless T is an array of known bound.

I don't understand the reason for the third, deleted overload. If T is an array of known bounds, the first two don't participate in overload resolution anyways, so why does the standard specifies the third one? Isn't this identical to leaving it out and specifying the first two overloads alone?

EDIT: Please note that I know why make_unique<T[N]> is not allowed. The question is not about that, it's about why the third overloaded is needed. AFAICT, the effect of having or not having it is identical, even wrt make_unique<T[N]>.

Community
  • 1
  • 1
Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • 2
    I think this has already been answered: http://stackoverflow.com/questions/16596950/why-is-make-uniquetn-disallowed (and http://stackoverflow.com/questions/16755415/make-unique-arrays-original-proposal-vs-final may also be interesting reading) – gx_ Dec 01 '13 at 14:46
  • 1
    @gx_ I don't think that answers it. It *might* explain how STL ended up with providing the third overload because of the way he implemented things in previous versions. But the end result still looks like the third overload is superfluous nowadays, not? – Daniel Frey Dec 01 '13 at 14:55
  • 4
    @DanielFrey I think the error message is worse w/o the third overload: There's no way to use a `static_assert` w/o the third (if the first two must reject arrays of known bound), and the error essentially is "there's no viable overload, here are two candidates" – dyp Dec 01 '13 at 14:57
  • 1
    @DyP QoI is probably the best explanation I've heard so far. But instead of `=delete`, the error message would be even better with a body containing `static_assert(sizeof(T)==0,"array of known bound not allowed");`. – Daniel Frey Dec 01 '13 at 15:03
  • 1
    @jogojapan I've seen that, but Andy's answer doesn't really answers it. He claims that without the third overload, the first one would match - which is not true given the standard text above (and it's easy to implement it that way). He also says that it allows implementations to emit helpful `static_assert` messages - which is impossible when the method is specified as `=delete;`. – Daniel Frey Dec 01 '13 at 15:12
  • @DanielFrey I personally suspect that Andy's quote from the original proposal is the best answer possible. But even if I am wrong and there is a better answer -- it should be given over at the older question, and your post should be marked as duplicate. (Don't take this as criticism; it's an interesting question, and having it in several versions on Stackoverflow isn't a bad thing.) – jogojapan Dec 01 '13 at 15:14
  • @jogojapan I added an answer to the other question and seeing it your way I agree that it is some kind of duplicate, although with the title and the style of the other Q it's hard to find it. I also wrote an email to STL, let's see what he has to say about this. :) – Daniel Frey Dec 01 '13 at 15:36

0 Answers0