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

### 2901. Variants cannot properly support allocators

Section: 20.7.3 [variant.variant] Status: C++17 Submitter: United States Opened: 2017-02-03 Last modified: 2020-09-06

Priority: 0

View all other issues in [variant.variant].

View all issues with C++17 status.

Discussion:

Addresses US 113

Variants cannot properly support allocators, as any assignment of a subsequent value throws away the allocator used at construction. This is not an easy problem to solve, so `variant` would be better served dropping the illusion of allocator support for now, leaving open the possibility to provide proper support once the problems are fully understood.

Proposed change: Strike the 8 allocator aware constructor overloads from the class definition, and strike 20.7.2.1 [variant.ctor] p34/35. Strike clause 20.7.12 [variant.traits]. Strike the specialization of `uses_allocator` for `variant` in the `<variant>` header synopsis, 20.7.1 [variant.general].

[2017-02-28, Kona, Casey provides wording]

[2017-06-29 Moved to Tentatively Ready after 7 positive votes on c++std-lib.]

[2017-07 Toronto Moved to Immediate]

Proposed resolution:

This wording is relative to N4659.

1. Change 20.7.2 [variant.syn], header `<variant>` synopsis, as follows:

   >     […]
   >     //  [variant.traits], allocator-related traits
   >     template <class T, class Alloc> struct uses_allocator;
   >     template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc>;

2. Change 20.7.3 [variant.variant], class template `variant` synopsis, as follows:

   >     […]
   >     // allocator-extended constructors
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc&);
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc&, const variant&);
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc&, variant&&);
   >     template <class Alloc, class T>
   >       variant(allocator_arg_t, const Alloc&, T&&);
   >     template <class Alloc, class T, class... Args>
   >       variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...);
   >     template <class Alloc, class T, class U, class... Args>
   >       variant(allocator_arg_t, const Alloc&, in_place_type_t<T>,
   >               initializer_list<U>, Args&&...);
   >     template <class Alloc, size_t I, class... Args>
   >       variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...);
   >     template <class Alloc, size_t I, class U, class... Args>
   >       variant(allocator_arg_t, const Alloc&, in_place_index_t<I>,
   >               initializer_list<U>, Args&&...);

3. Modify 20.7.3.2 [variant.ctor] as indicated:

   >     // allocator-extended constructors
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc& a);
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc& a, const variant& v);
   >     template <class Alloc>
   >       variant(allocator_arg_t, const Alloc& a, variant&& v);
   >     template <class Alloc, class T>
   >       variant(allocator_arg_t, const Alloc& a, T&& t);
   >     template <class Alloc, class T, class... Args>
   >       variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args);
   >     template <class Alloc, class T, class U, class... Args>
   >       variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>,
   >               initializer_list<U> il, Args&&... args);
   >     template <class Alloc, size_t I, class... Args>
   >       variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args);
   >     template <class Alloc, size_t I, class U, class... Args>
   >       variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>,
   >               initializer_list<U> il, Args&&... args);

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

   > > -35- Effects: Equivalent to the preceding constructors except that the contained value is constructed with uses-allocator construction (20.10.7.2 [allocator.uses.construction]).

4. Modify [variant.traits] as indicated:

   >     template <class... Types, class Alloc>
   >     struct uses_allocator<variant<Types...>, Alloc> : true_type { };

   > > -1- Requires: `Alloc` shall be an Allocator (16.4.4.6 [allocator.requirements]).

   > > -2- [Note: Specialization of this trait informs other library components that variant can be constructed with an allocator, even though it does not have a nested `allocator_type`. — end note]