[PATCH v2] libstdc++: Implement LWG4222 'expected' constructor from a single value missing a constraint

Yihan Wang yronglin777@gmail.com
Thu Aug 14 12:32:18 GMT 2025


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 <yronglin777@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() );
+}
-- 
2.39.5



More information about the Libstdc++ mailing list