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. 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 > >
