Title
Flat maps' deduction guide needs to default Allocator to be useful
Status
c++23
Section
[flat.map.defn][flat.multimap.defn]
Submitter
Johel Ernesto Guerrero Peña

Created on 2022-09-25.00:00:00 last changed 4 months ago

Messages

Date: 2023-02-13.11:31:32

Proposed resolution:

This wording is relative to N4917.

  1. Modify [container.adaptors.general] as indicated:

    -8- The following exposition-only alias template may appear in deduction guides for container adaptors:

    template<class Allocator, class T>
      using alloc-rebind =                                 // exposition only
        typename allocator_traits<Allocator>::template rebind_alloc<T>;
    
    
  2. Modify [flat.map.defn], class template flat_map synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<byte>>
      flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_map(from_range_t, R&&, Allocator)
        -> flat_map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
    […]
    
  3. Modify [flat.multimap.defn], class template flat_multimap synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<byte>>
      flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_multimap(from_range_t, R&&, Allocator)
        -> flat_multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>>;
    […]
    
  4. Modify [flat.set.defn], class template flat_set synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
             class Allocator = allocator<ranges::range_value_t<R>>>
      flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_set<ranges::range_value_t<R>, Compare,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_set(from_range_t, R&&, Allocator)
        -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    […]
    
  5. Modify [flat.multiset.defn], class template flat_multiset synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
             class Allocator = allocator<ranges::range_value_t<R>>>
      flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_multiset<ranges::range_value_t<R>, Compare,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_multiset(from_range_t, R&&, Allocator)
        -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    […]
    
Date: 2023-02-13.00:00:00

[ 2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Immediate → WP. ]

Date: 2023-02-09.02:30:45

[ Issaquah 2023-02-07; LWG ]

Edited proposed resolution to fix missing > in guides for maps. Move to Immediate for C++23

Date: 2023-01-15.00:00:00

[ 2023-01-11; Jonathan Wakely provides improved wording ]

During LWG telecon Tim pointed out that because allocator<void> does not meet the Cpp17Allocator requirements, it might not "qualify as an allocator" and so would cause the deduction guides to not participate in overload resolution, as per [container.adaptors.general] p6 (6.4). Use allocator<byte> instead.

Date: 2022-10-15.00:00:00

[ 2022-10-19; Jonathan provides improved wording ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify [container.adaptors.general] as indicated:

    -8- The following exposition-only alias templates may appear in deduction guides for container adaptors:

    template<class Container>
      using cont-key-type =                                // exposition only
        remove_const_t<typename Container::value_type::first_type>;
    template<class Container>
      using cont-mapped-type =                             // exposition only
        typename Container::value_type::second_type;
    template<class Allocator, class T>
      using alloc-rebind =                             // exposition only
        typename allocator_traits<Allocator>::template rebind_alloc<T>;
    
    
  2. Modify [flat.map.defn], class template flat_map synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<void>>
      flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_map(from_range_t, R&&, Allocator)
        -> flat_map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>;
    […]
    
  3. Modify [flat.multimap.defn], class template flat_multimap synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<void>>
      flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_multimap(from_range_t, R&&, Allocator)
        -> flat_multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>,
             vector<range-key-type<R>, alloc-rebind<Allocator, range-key-type<R>>,
             vector<range-mapped-type<R>, alloc-rebind<Allocator, range-mapped-type<R>>>;
    […]
    
  4. Modify [flat.set.defn], class template flat_set synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
             class Allocator = allocator<ranges::range_value_t<R>>>
      flat_set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_set<ranges::range_value_t<R>, Compare,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_set(from_range_t, R&&, Allocator)
        -> flat_set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    […]
    
  5. Modify [flat.multiset.defn], class template flat_multiset synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>,
             class Allocator = allocator<ranges::range_value_t<R>>>
      flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_multiset<ranges::range_value_t<R>, Compare,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    
    template<ranges::input_range R, class Allocator>
      flat_multiset(from_range_t, R&&, Allocator)
        -> flat_multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>,
             vector<ranges::range_value_t<R>, alloc-rebind<Allocator, ranges::range_value_t<R>>>>;
    […]
    
Date: 2022-09-15.00:00:00

[ 2022-09-28; LWG telecon ]

We should not just ignore the allocator, it should be rebound and used for the two container types.

Previous resolution [SUPERSEDED]:

This wording is relative to N4917.

  1. Modify [flat.map.defn], class template flat_map synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<void>>
      flat_map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_map<range-key-type<R>, range-mapped-type<R>, Compare>;
    […]
    
  2. Modify [flat.multimap.defn], class template flat_multimap synopsis, as indicated:

    […]
    template<ranges::input_range R, class Compare = less<range-key-type<R>>,
             class Allocator = allocator<void>>
      flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())
        -> flat_multimap<range-key-type<R>, range-mapped-type<R>, Compare>;
    […]
    
Date: 2022-09-25.00:00:00

This originated from the editorial issue #5800.

P0429R9 added some deduction guides with a non-defaulted Allocator template parameter and a corresponding function parameter that is defaulted. Since the template parameter Allocator is not defaulted, these deduction guides are never used.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2023-02-13 11:31:32adminsetmessages: + msg13385
2023-02-13 11:31:32adminsetstatus: immediate -> wp
2023-02-09 02:30:45adminsetmessages: + msg13303
2023-02-09 02:30:45adminsetstatus: open -> immediate
2023-01-11 18:22:42adminsetmessages: + msg13197
2022-10-19 19:43:42adminsetmessages: + msg12871
2022-10-06 17:09:10adminsetmessages: + msg12841
2022-10-06 17:09:10adminsetstatus: new -> open
2022-09-25 11:23:04adminsetmessages: + msg12814
2022-09-25 00:00:00admincreate