On Wed, May 6, 2026 at 10:10 PM Jonathan Wakely <[email protected]> wrote:

> On Wed, 6 May 2026 at 15:49, Tomasz Kaminski <[email protected]> wrote:
> >
> >
> >
> > On Wed, May 6, 2026 at 4:16 PM Jonathan Wakely <[email protected]>
> wrote:
> >>
> >> Since C++20 the std::tuple move constructor should be constrained (as
> >> modified by LWG 2899).
> >>
> >> We already define the move constructor as defaulted, but it's not
> >> implicitly defined as deleted for non-move-constructible element types
> >> because the _Tuple_impl(_Tuple_impl&&) constructor is user-provided and
> >> unconstrained. For C++20 and later we use a requires-clause to constrain
> >> the defaulted tuple(tuple&&) constructor.
> >>
> >> Ideally we'd make this change pre-C++20 as well, but that's harder to do
> >> without using a requires-clause, so this change is only for C++20 and
> >> later. I think that's OK, but if we need to change it for pre-C++20
> >> later we can consider inheriting from _Enable_copy_move<..., tuple> to
> >> make the defaulted move constructor defined as deleted.
> >>
> >> libstdc++-v3/ChangeLog:
> >>
> >>         PR libstdc++/78302
> >>         PR libstdc++/71301
> >>         * include/std/tuple [C++20] (tuple(tuple&&)): Add
> >>         requires-clause.
> >>         * testsuite/20_util/tuple/cons/78302.cc: New test.
> >> ---
> >>
> >> Tested x86_64-linux.
> >>
> >>  libstdc++-v3/include/std/tuple                     |  4 +++-
> >>  libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc | 11 +++++++++++
> >>  2 files changed, 14 insertions(+), 1 deletion(-)
> >>  create mode 100644 libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc
> >>
> >> diff --git a/libstdc++-v3/include/std/tuple
> b/libstdc++-v3/include/std/tuple
> >> index cbacd5a3c977..64b96fe4f599 100644
> >> --- a/libstdc++-v3/include/std/tuple
> >> +++ b/libstdc++-v3/include/std/tuple
> >> @@ -954,7 +954,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>
> >>        constexpr tuple(const tuple&) = default;
> >>
> >> -      constexpr tuple(tuple&&) = default;
> >> +      constexpr
> >> +      tuple(tuple&&) requires (is_move_constructible_v<_Elements> &&
> ...)
> >
> > Could you add test for tuple of references (lvalue and rvalue)? I think
> the traits
> > gives correct result,  but I am not sure.
> >>
> >> +       = default;
> >>
> >>        template<typename... _UTypes>
> >>         requires (__constructible<const _UTypes&...>())
> >> diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc
> b/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc
> >> new file mode 100644
> >> index 000000000000..b3c6bd67fd27
> >> --- /dev/null
> >> +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/78302.cc
> >> @@ -0,0 +1,11 @@
> >> +// { dg-do compile { target c++20 } }
> >> +
> >> +// Bug 78302 is_move_constructible_v<tuple<nonmovable>> should be false
> >> +// LWG 2899. is_(nothrow_)move_constructible and tuple, optional and
> unique_ptr
> >> +
> >> +#include <tuple>
> >> +#include <type_traits>
> >> +
> >> +struct NotMovable { NotMovable(NotMovable&&) = delete; };
> >> +static_assert(!std::is_move_constructible_v<std::tuple<NotMovable>>);
> >> +static_assert(std::is_nothrow_move_constructible_v<std::tuple<int>>);
>
> Is this good enough?
>
>
> #include <tuple>
> #include <type_traits>
>
> struct NotMovable { NotMovable(NotMovable&&) = delete; };
> static_assert(!std::is_move_constructible_v<std::tuple<NotMovable>>);
> static_assert(!std::is_move_constructible_v<std::tuple<int, NotMovable>>);
> static_assert(!std::is_move_constructible_v<std::tuple<int&, NotMovable>>);
> static_assert(!std::is_move_constructible_v<std::tuple<int&&,
> NotMovable>>);
> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int>>);
> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&>>);
> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&&>>);
> static_assert(std::is_nothrow_move_constructible_v<std::tuple<int&&,
> int&>>);
>
Add them to test file, so I do not need to check is_move_constructible_v on
reference,
when looking at it. LGTM with that.

>
> (It passes)
>
>

Reply via email to