Skip to content

Commit 6bad24d

Browse files
<expected>: Workaround for DevCom-10655311 "Class derived from std::expected can't be constructed with bool value type" (#4664)
1 parent a35859c commit 6bad24d

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

stl/inc/expected

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,18 @@ public:
310310
template <class _Uty = _Ty>
311311
requires (!is_same_v<remove_cvref_t<_Uty>, in_place_t> && !is_same_v<remove_cvref_t<_Uty>, expected>
312312
&& !_Is_specialization_v<remove_cvref_t<_Uty>, unexpected>
313-
&& (!is_same_v<remove_cv_t<_Ty>, bool> || !_Is_specialization_v<remove_cvref_t<_Uty>, expected>)
313+
&& (!is_same_v<remove_cv_t<_Ty>, bool>
314+
#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10655311
315+
|| !_Is_specialization_v<remove_cvref_t<_Uty>, expected>
316+
#else // ^^^ no workaround / workaround vvv
317+
|| !_Is_specialization_v<remove_cvref_t<_Uty>, _STD expected>
318+
#endif // ^^^ workaround ^^^
319+
)
314320
&& is_constructible_v<_Ty, _Uty>)
315321
constexpr explicit(!is_convertible_v<_Uty, _Ty>)
316322
expected(_Uty&& _Other) noexcept(is_nothrow_constructible_v<_Ty, _Uty>) // strengthened
317-
: _Value(_STD forward<_Uty>(_Other)), _Has_value(true) {}
323+
: _Value(_STD forward<_Uty>(_Other)), _Has_value(true) {
324+
}
318325

319326
template <class _UErr>
320327
requires is_constructible_v<_Err, const _UErr&>

tests/std/tests/P0323R12_expected/test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,30 @@ void test_lwg_3843() {
23192319
static_assert(copyable<expected<any, int>>);
23202320
static_assert(copyable<expected<void, any>>);
23212321

2322+
// Test workaround for DevCom-10655311: Class derived from std::expected can't be constructed with bool value type
2323+
template <class T, class E>
2324+
class DerivedFromExpected : private expected<T, E> {
2325+
public:
2326+
using expected<T, E>::expected;
2327+
using expected<T, E>::value;
2328+
};
2329+
2330+
static_assert(is_constructible_v<DerivedFromExpected<bool, int>, bool>);
2331+
static_assert(is_constructible_v<DerivedFromExpected<bool, int>, const bool&>);
2332+
2333+
constexpr bool test_inherited_constructors() {
2334+
DerivedFromExpected<bool, int> wrapped_false_val(false);
2335+
assert(!wrapped_false_val.value());
2336+
2337+
constexpr bool true_val = true;
2338+
DerivedFromExpected<bool, int> wrapped_true_val(true_val);
2339+
assert(wrapped_true_val.value());
2340+
2341+
return true;
2342+
}
2343+
2344+
static_assert(test_inherited_constructors());
2345+
23222346
int main() {
23232347
test_unexpected::test_all();
23242348
static_assert(test_unexpected::test_all());
@@ -2335,4 +2359,5 @@ int main() {
23352359

23362360
test_reinit_regression();
23372361
test_lwg_3843();
2362+
test_inherited_constructors();
23382363
}

0 commit comments

Comments
 (0)