Thanks for your suggestion, comments addressed in [PATCH v3] libstdc++:
Implement LWG4222 'expected' constructor from a single value missing a
constraint

Patrick Palka <ppa...@redhat.com> 于2025年8月16日周六 03:58写道:

> On Thu, 14 Aug 2025, Yihan Wang wrote:
>
> > libstdc++-v3/ChangeLog:
> >
> >       * include/std/expected: Add missing constraint as per LWG 4222.
> >       * testsuite/20_util/expected/lwg4222.cc: New test.
> >
> > Signed-off-by: Yihan Wang <yronglin...@gmail.com>
> > ---
> >  libstdc++-v3/include/std/expected             |  1 +
> >  .../testsuite/20_util/expected/lwg4222.cc     | 32 +++++++++++++++++++
> >  2 files changed, 33 insertions(+)
> >  create mode 100644 libstdc++-v3/testsuite/20_util/expected/lwg4222.cc
> >
> > diff --git a/libstdc++-v3/include/std/expected
> b/libstdc++-v3/include/std/expected
> > index 60f1565f15b..4eaaab693e1 100644
> > --- a/libstdc++-v3/include/std/expected
> > +++ b/libstdc++-v3/include/std/expected
> > @@ -474,6 +474,7 @@ namespace __expected
> >        template<typename _Up = remove_cv_t<_Tp>>
> >       requires (!is_same_v<remove_cvref_t<_Up>, expected>)
> >         && (!is_same_v<remove_cvref_t<_Up>, in_place_t>)
> > +       && (!is_same_v<remove_cvref_t<_Up>, unexpect_t>)
> >         && is_constructible_v<_Tp, _Up>
> >         && (!__expected::__is_unexpected<remove_cvref_t<_Up>>)
> >         && __expected::__not_constructing_bool_from_expected<_Tp, _Up>
> > diff --git a/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc
> b/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc
> > new file mode 100644
> > index 00000000000..2483afba853
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc
> > @@ -0,0 +1,32 @@
> > +// { dg-do compile { target c++23 } }
> > +
> > +// LWG 4222. 'expected' constructor from a single value missing a
> constraint
> > +
> > +#include <expected>
> > +#include <type_traits>
> > +#include <testsuite_hooks.h>
> > +
> > +struct T {
> > +  explicit T(auto) {}
> > +};
> > +struct E {
> > +  E(int) {}
> > +};
> > +
> > +struct V {
> > + explicit V(std::unexpect_t) {}
> > +};
> > +
> > +static_assert(!std::is_constructible_v<std::expected<T, E>,
> std::unexpect_t>);
> > +static_assert(!std::is_constructible_v<std::expected<T, E>,
> std::unexpect_t &>);
> > +static_assert(!std::is_constructible_v<std::expected<T, E>,
> std::unexpect_t &&>);
> > +static_assert(!std::is_constructible_v<std::expected<T, E>, const
> std::unexpect_t>);
> > +static_assert(!std::is_constructible_v<std::expected<T, E>, const
> std::unexpect_t &>);
> > +static_assert(!std::is_constructible_v<std::expected<T, E>, const
> std::unexpect_t &&>);
> > +
> > +void test() {
> > +  std::expected<V, int> e1(std::in_place, std::unexpect);
> > +  VERIFY( e1.has_value() );
> > +  std::expected<int, V> e2(std::unexpect, std::unexpect);
> > +  VERIFY( !e2.has_value() );
>
> These VERIFY asserts aren't actually checked because this test file is
> specified as a compile-only test via 'dg-do compile'.
>
> We can either turn this into a runnable test by specifying 'dg-do run'
> (and defining main()), or we can keep it a compile-only test and make
> test() constexpr and add something like static_assert(test()).
>
> (In theory constexpr tests are stronger than runtime tests since they
> diagnose UB, so I generally prefer the latter.  Ideally we should have
> both a runtime and constexpr test but that seems overkill here.)
>
> > +}
> > --
> > 2.39.5
> >
> >
>
>

Reply via email to