Created on 2020-05-01.00:00:00 last changed 50 months ago
Proposed resolution:
This wording is relative to N4861.
Modify [tuple.cnstr] as indicated:
template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&... u);-11- Constraints: sizeof...(Types) equals sizeof...(UTypes) and sizeof...(Types) ≥ 1 and is_constructible_v<Ti, Ui> is true for all i and conjunction_v<is_aggregate<remove_reference_t<Ti>>, negation<is_same<remove_reference_t<Ti>, remove_reference_t<Ui>>>> is false for all i.
Modify [optional.ctor] as indicated:
template<class U = T> constexpr explicit(see below) optional(U&& v);-22- Constraints: is_constructible_v<T, U> is true, is_same_v<remove_cvref_t<U>, in_place_t> is false,
andis_same_v<remove_cvref_t<U>, optional> is false, and conjunction_v<is_aggregate<T>, negation<is_same<T, remove_reference_t<U>>>> is false.
[ 2020-11-09 Status changed: Tentatively NAD → NAD. ]
[ 2020-06-23; LEWG Telecon ]
POLL: Make ({val}) work again, at the risk of non-transparency of tuple constructors and further complicating the tuple and optional overload set.
SF F N A SA 0 5 6 9 0
No consensus for change. Close as Not a defect.
[ 2020-06-11; LWG Telecon: Status changed: New → LEWG. ]
Ask LEWG if it's desirable to make ({val}) work again. Tomasz would prefer it to be explicit e.g. via std::in_place.
[ 2020-05-09; Reflector prioritization ]
Set priority to 2 after reflector discussions.
For reference, see this gcc bug report.
Constructing a tuple or optional from an element value of an aggregate is broken in C++20. tuple<c> t({val}); and optional<c> t({val}); invoked a non-forwarding constructor before, but now the perfect-forwarding converting constructors are a match, because the element is constructible from {val}. But it's not convertible, so overload resolution chooses the explicit constructor, and the initialization fails. Tim Song explains the overload resolution in this reflector discussion. Now that we understand that C++17 called the non-forwarding conversion constructor, and C++20 tries to use the forwarding conversion constructor, we have the solution. SFINAE away the forwarding conversion constructor when it would convert an aggregate. This also means that tuple<c> t(0); won't work, which is unfortunate because tuple<c>/optional<c> no longer mirrors what c can do. That's okay; in this LWG issue, we first restore feature parity with C++17, and later, as an extension, enable such initializations so that tuple/optional mirrors what c can do in C++20. The proposed wording below has been implemented and tested.History | |||
---|---|---|---|
Date | User | Action | Args |
2020-11-09 20:22:58 | admin | set | messages: + msg11538 |
2020-06-27 17:18:07 | admin | set | messages: + msg11351 |
2020-06-27 17:18:07 | admin | set | status: lewg -> nad |
2020-06-11 16:18:56 | admin | set | messages: + msg11328 |
2020-06-11 16:18:56 | admin | set | status: new -> lewg |
2020-05-09 19:39:43 | admin | set | messages: + msg11279 |
2020-05-03 11:58:58 | admin | set | messages: + msg11262 |
2020-05-01 00:00:00 | admin | create |