This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD Arrays status.

### 2255. [arrays.ts] `dynarray` constructor ambiguity

Section: 99 [arrays.ts::dynarray.cons] Status: NAD Arrays Submitter: Jonathan Wakely Opened: 2013-04-23 Last modified: 2016-03-08

Priority: 0

View all issues with NAD Arrays status.

Discussion:

Addresses: arrays.ts

These constructors can interact badly::

>     template<class Alloc>
>       dynarray(size_type c, const Alloc& alloc);
>     dynarray(size_type c, const T& v);

Unless the second argument is a value of exactly the type `T` you will get the first constructor, i.e. all of these will fail to compile:

>     dynarray<long> dlong(1, 1);   // 1 is not long
>     dynarray<float> dflt(1, 1.0);  // 1.0 is not float
>     dynarray<int*> dptr(1, nullptr);  // nullptr is not int*
>     dynarray<void*> doh(1, 0);  // 0 is not void*

The `nullptr` case is particularly annoying, a user trying to do the right thing by saying `nullptr` instead of `NULL` still gets the wrong result.

The constructor taking an allocator requires that "`Alloc` shall meet the requirements for an Allocator" but doesn't actually say "shall not participate in overload resolution unless ..."

I believe we have no precedent for using SFINAE to check "the requirements for an Allocator" because it's a pretty complicated set of requirements. We could say it shall not participate in overload resolution if `Alloc` is implicitly convertible to `value_type`.

Alternatively, we could follow the same approach used by other types that can be constructed with an unconstrained allocator type and use `std::allocator_arg_t` as the first argument instead of adding an allocator after the other arguments.

[2013-09 Chicago:]

Move to Deferred. This feature will ship after C++14 and should be revisited then.

[2014-06-06 pre-Rapperswil]

This issue has been reopened as arrays-ts.

[2014-06-16 Rapperswil]

Move to Ready for alternative A

Previous resolution [SUPERSEDED]:

> 1. Either use the correct way to unambiguously call a constructor taking any type of allocator, i.e. change the constructors to take `dynarray(std::allocator_arg_t, const Alloc&, ...)` by modifying both the synopsis 99 [arrays.ts::dynarray.overview] p2 and 99 [arrays.ts::dynarray.cons] before p9 like so:

>    >     template <class Alloc>
>    >       dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);

> 2. or constrain the problematic constructor by adding a new paragraph to 99 [arrays.ts::dynarray.cons]:

>    >     template <class Alloc>
>    >       dynarray(size_type c, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(size_type c, const T& v, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(const dynarray& d, const Alloc& alloc);
>    >     template <class Alloc>
>    >       dynarray(initializer_list<T>, const Alloc& alloc);

>    > > -9- Requires: `Alloc` shall meet the requirements for an Allocator (16.4.4.6 [allocator.requirements]).

>    > > -10- Effects: Equivalent to the preceding constructors except that each element is constructed with uses-allocator construction (20.10.7.2 [allocator.uses.construction]).

>    > > -?- Remarks: The first constructor shall not participate in overload resolution unless `Alloc` is not implicitly convertible to `T`.

[2014/11 Urbana]

Held at Ready status, pending clarification of Arrays TS

Proposed resolution:

1. Use the correct way to unambiguously call a constructor taking any type of allocator, i.e. change the constructors to take `dynarray(std::allocator_arg_t, const Alloc&, ...)` by modifying both the synopsis 99 [arrays.ts::dynarray.overview] p2 and 99 [arrays.ts::dynarray.cons] before p9 like so:

   >     template <class Alloc>
   >       dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc);
   >     template <class Alloc>
   >       dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc);
   >     template <class Alloc>
   >       dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc);
   >     template <class Alloc>
   >       dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc);