On Mon, 25 May 2026, 10:37 Tomasz Kaminski, <[email protected]> wrote:

>
>
> On Fri, May 22, 2026 at 1:39 AM Jonathan Wakely <[email protected]>
> wrote:
>
>> The standard requires that these deduction guides are constrained to
>> only accept a type that qualifies as an allocator for the second
>> templates argument.
>>
>> libstdc++-v3/ChangeLog:
>>
>>         * include/bits/stl_deque.h: Add missing constraint on allocator
>>         type in deduction guide.
>>         * include/bits/stl_vector.h: Likewise.
>>         * include/debug/deque: Likewise.
>>         * include/debug/vector: Likewise.
>>         * testsuite/23_containers/deque/cons/deduction_c++23.cc: Check
>>         that deduction fails for a type which does not qualify as an
>>         allocator.
>>         * testsuite/23_containers/vector/cons/deduction_c++23.cc:
>>         Likewise.
>> ---
>>
>> Tested x86_64-linux.
>>
> Ah, the wording from
> https://eel.is/c++draft/container.requirements#sequence.reqmts-69.3
> still applies. And this is visible because CTAD should SFINAE in that
> case, whil is instantiation
> will be ill-formed.
>

Yes, it took me a minute to realize that it was observable. The new tests
fail with errors outside the immediate context if these constraints are
missing.



> LGTM, thanks.
>
>>
>>  libstdc++-v3/include/bits/stl_deque.h              |  2 +-
>>  libstdc++-v3/include/bits/stl_vector.h             |  2 +-
>>  libstdc++-v3/include/debug/deque                   |  2 +-
>>  libstdc++-v3/include/debug/vector                  |  2 +-
>>  .../23_containers/deque/cons/deduction_c++23.cc    | 14 ++++++++++++++
>>  .../23_containers/vector/cons/deduction_c++23.cc   | 14 ++++++++++++++
>>  6 files changed, 32 insertions(+), 4 deletions(-)
>>  create mode 100644
>> libstdc++-v3/testsuite/23_containers/deque/cons/deduction_c++23.cc
>>  create mode 100644
>> libstdc++-v3/testsuite/23_containers/vector/cons/deduction_c++23.cc
>>
>> diff --git a/libstdc++-v3/include/bits/stl_deque.h
>> b/libstdc++-v3/include/bits/stl_deque.h
>> index aebe865ffc1a..28f61d2ccd37 100644
>> --- a/libstdc++-v3/include/bits/stl_deque.h
>> +++ b/libstdc++-v3/include/bits/stl_deque.h
>> @@ -2414,7 +2414,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>>
>>  #if __glibcxx_containers_ranges // C++ >= 23
>>    template<ranges::input_range _Rg,
>> -          typename _Alloc = allocator<ranges::range_value_t<_Rg>>>
>> +          __allocator_like _Alloc =
>> allocator<ranges::range_value_t<_Rg>>>
>>      deque(from_range_t, _Rg&&, _Alloc = _Alloc())
>>        -> deque<ranges::range_value_t<_Rg>, _Alloc>;
>>  #endif
>> diff --git a/libstdc++-v3/include/bits/stl_vector.h
>> b/libstdc++-v3/include/bits/stl_vector.h
>> index 0c9b74fdbb24..9ddf35502e69 100644
>> --- a/libstdc++-v3/include/bits/stl_vector.h
>> +++ b/libstdc++-v3/include/bits/stl_vector.h
>> @@ -2383,7 +2383,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
>>
>>  #if __glibcxx_containers_ranges // C++ >= 23
>>    template<ranges::input_range _Rg,
>> -          typename _Alloc = allocator<ranges::range_value_t<_Rg>>>
>> +          __allocator_like _Alloc =
>> allocator<ranges::range_value_t<_Rg>>>
>>      vector(from_range_t, _Rg&&, _Alloc = _Alloc())
>>        -> vector<ranges::range_value_t<_Rg>, _Alloc>;
>>  #endif
>> diff --git a/libstdc++-v3/include/debug/deque
>> b/libstdc++-v3/include/debug/deque
>> index 9fba4ffc4997..00b4220051e7 100644
>> --- a/libstdc++-v3/include/debug/deque
>> +++ b/libstdc++-v3/include/debug/deque
>> @@ -715,7 +715,7 @@ namespace __debug
>>
>>  #if __glibcxx_containers_ranges // C++ >= 23
>>    template<ranges::input_range _Rg,
>> -          typename _Alloc = allocator<ranges::range_value_t<_Rg>>>
>> +          __allocator_like _Alloc =
>> allocator<ranges::range_value_t<_Rg>>>
>>      deque(from_range_t, _Rg&&, _Alloc = _Alloc())
>>        -> deque<ranges::range_value_t<_Rg>, _Alloc>;
>>  #endif
>> diff --git a/libstdc++-v3/include/debug/vector
>> b/libstdc++-v3/include/debug/vector
>> index 61e5ff78a7a4..56645d1e92c3 100644
>> --- a/libstdc++-v3/include/debug/vector
>> +++ b/libstdc++-v3/include/debug/vector
>> @@ -1001,7 +1001,7 @@ namespace __debug
>>
>>  #if __glibcxx_containers_ranges // C++ >= 23
>>    template<ranges::input_range _Rg,
>> -          typename _Alloc = allocator<ranges::range_value_t<_Rg>>>
>> +          __allocator_like _Alloc =
>> allocator<ranges::range_value_t<_Rg>>>
>>      vector(from_range_t, _Rg&&, _Alloc = _Alloc())
>>        -> vector<ranges::range_value_t<_Rg>, _Alloc>;
>>  #endif
>> diff --git
>> a/libstdc++-v3/testsuite/23_containers/deque/cons/deduction_c++23.cc
>> b/libstdc++-v3/testsuite/23_containers/deque/cons/deduction_c++23.cc
>> new file mode 100644
>> index 000000000000..5893de92dc6f
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/23_containers/deque/cons/deduction_c++23.cc
>> @@ -0,0 +1,14 @@
>> +// { dg-do compile { target c++23 } }
>> +
>> +#include <deque>
>> +#include <testsuite_iterators.h>
>> +
>> +using Range = __gnu_test::test_input_range<int>;
>> +
>> +template<typename Alloc>
>> +concept can_deduce_deque = requires(Range r, Alloc a) {
>> +  std::deque(std::from_range, r, a);
>> +};
>> +
>> +// Deduction should fail because int does not qualify as an allocator.
>> +static_assert( ! can_deduce_deque<int> );
>> diff --git
>> a/libstdc++-v3/testsuite/23_containers/vector/cons/deduction_c++23.cc
>> b/libstdc++-v3/testsuite/23_containers/vector/cons/deduction_c++23.cc
>> new file mode 100644
>> index 000000000000..1a442a8ed5c2
>> --- /dev/null
>> +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/deduction_c++23.cc
>> @@ -0,0 +1,14 @@
>> +// { dg-do compile { target c++23 } }
>> +
>> +#include <vector>
>> +#include <testsuite_iterators.h>
>> +
>> +using Range = __gnu_test::test_input_range<int>;
>> +
>> +template<typename Alloc>
>> +concept can_deduce_vector = requires(Range r, Alloc a) {
>> +  std::vector(std::from_range, r, a);
>> +};
>> +
>> +// Deduction should fail because int does not qualify as an allocator.
>> +static_assert( ! can_deduce_vector<int> );
>> --
>> 2.54.0
>>
>>

Reply via email to