*_ptr<T[N]>
Section: 20.3.1 [unique.ptr] Status: CD1 Submitter: Herb Sutter Opened: 2007-10-04 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [unique.ptr].
View all issues with CD1 status.
Discussion:
Please don't provide *_ptr<T[N]>
. It doesn't enable any useful
bounds-checking (e.g., you could imagine that doing op++
on a
shared_ptr<T[N]>
yields a shared_ptr<T[N-1]>
, but that promising path
immediately falters on op--
which can't reliably dereference because we
don't know the lower bound). Also, most buffers you'd want to point to
don't have a compile-time known size.
To enable any bounds-checking would require run-time information, with
the usual triplet: base (lower bound), current offset, and max offset
(upper bound). And I can sympathize with the point of view that you
wouldn't want to require this on *_ptr
itself. But please let's not
follow the <T[N]>
path, especially not with additional functions to
query the bounds etc., because this sets wrong user expectations by
embarking on a path that doesn't go all the way to bounds checking as it
seems to imply.
If bounds checking is desired, consider a checked_*_ptr
instead (e.g.,
checked_shared_ptr
). And make the interfaces otherwise identical so that
user code could easily #define/typedef
between prepending checked_
on
debug builds and not doing so on release builds (for example).
Note that some may object that checked_*_ptr
may seem to make the smart
pointer more like vector
, and we don't want two ways to spell vector
. I
don't agree, but if that were true that would be another reason to
remove *_ptr<T[N]>
which equally makes the smart pointer more like
std::array.
:-)
[ Bellevue: ]
Suggestion that fixed-size array instantiations are going to fail at compile time anyway (if we remove specialization) due to pointer decay, at least that appears to be result from available compilers.
So concerns about about requiring static_assert seem unfounded.
After a little more experimentation with compiler, it appears that fixed size arrays would only work at all if we supply these explicit specialization. So removing them appears less breaking than originally thought.
straw poll unanimous move to Ready.
Proposed resolution:
Change the synopsis under 20.3.1 [unique.ptr] p2:
... template<class T> struct default_delete; template<class T> struct default_delete<T[]>;template<class T, size_t N> struct default_delete<T[N]>;template<class T, class D = default_delete<T>> class unique_ptr; template<class T, class D> class unique_ptr<T[], D>;template<class T, class D, size_t N> class unique_ptr<T[N], D>;...
Remove the entire section [unique.ptr.dltr.dflt2] default_delete<T[N]>
.
Remove the entire section [unique.ptr.compiletime] unique_ptr
for array objects with a compile time length
and its subsections: [unique.ptr.compiletime.dtor], [unique.ptr.compiletime.observers],
[unique.ptr.compiletime.modifiers].