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

Reply via email to