Created on 2025-08-20.00:00:00 last changed 7 days ago
Proposed resolution:
This wording is relative to N5014.
Modify [indirect.ctor] as indicated:
template<class U = T> constexpr explicit indirect(U&& u);-17- Constraints:
(17.1) — is_same_v<remove_cvref_t<U>, indirect> is `false`,
(17.2) — is_same_v<remove_cvref_t<U>, in_place_t> is `false`, and
(17.3) — is_constructible_v<T, U> is `true`, and(17.4) — is_default_constructible_v<Allocator> is `true`.
-?- Mandates: is_constructible_v<T, U> is `true`.
-18- Effects: […]template<class U = T> constexpr explicit indirect(allocator_arg_t, const Allocator& a, U&& u);-19- Constraints:
(19.1) — is_same_v<remove_cvref_t<U>, indirect> is `false`, and
(19.2) — is_same_v<remove_cvref_t<U>, in_place_t> is `false`.
, and
(19.3) — is_constructible_v<T, U> is `true`-?- Mandates: is_constructible_v<T, U> is `true`.
-20- Effects: […]template<class... Us> constexpr explicit indirect(in_place_t, Us&&... us);-21- Constraints:
(21.1) — is_constructible_v<T, Us...> is `true`, and
(21.2) —is_default_constructible_v<Allocator> is `true`.-?- Mandates: is_constructible_v<T, Us...> is `true`.
-22- Effects: […]template<class... Us> constexpr explicit indirect(allocator_arg_t, const Allocator& a, in_place_t, Us&& ...us);-23-
-24- Effects: […]ConstraintsMandates: is_constructible_v<T, Us...> is `true`template<class I, class... Us> constexpr explicit indirect(in_place_t, initializer_list<I> ilist, Us&&... us);-25- Constraints:
(25.1) — is_constructible_v<T, initializer_list<I>&, Us...> is `true`, and
(25.2) —is_default_constructible_v<Allocator> is `true`.-?- Mandates: is_constructible_v<T, initializer_list<I>&, Us...> is `true`.
-26- Effects: […]template<class I, class... Us> constexpr explicit indirect(allocator_arg_t, const Allocator& a, in_place_t, initializer_list<I> ilist, Us&&... us);-27-
-28- Effects: […]ConstraintsMandates: is_constructible_v<T, initializer_list<I>&, Us...> is `true`
Modify [polymorphic.ctor] as indicated:
template<class U = T> constexpr explicit polymorphic(U&& u);-12- Constraints: Where `UU` is remove_cvref_t<U>,
(12.1) — is_same_v<UU, polymorphic> is `false`,
(12.2) — derived_from<UU, T> is `true`,(12.3) — is_constructible_v<UU, U> is `true`,
(12.4) — is_copy_constructible_v<UU> is `true`,
(12.5) — `UU` is not a specialization of `in_place_type_t`, and
(12.6) — is_default_constructible_v<Allocator> is `true`.
-?- Mandates: derived_from<UU, T> is `true`.
-13- Effects: […]template<class U = T> constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, U&& u);-14- Constraints: Where `UU` is remove_cvref_t<U>,
(14.1) — is_same_v<UU, polymorphic> is `false`,
(14.2) — derived_from<UU, T> is `true`,(14.3) — is_constructible_v<UU, U> is `true`,
(14.4) — is_copy_constructible_v<UU> is `true`, and
(14.5) — `UU` is not a specialization of `in_place_type_t`.
-?- Mandates: derived_from<UU, T> is `true`.
-15- Effects: […]template<class U, class... Ts> constexpr explicit polymorphic(in_place_type_t<U>, Ts&&... ts);-16- Constraints:
(16.1) — is_same_v<remove_cvref_t<U>, U> is `true`,
(16.2) — derived_from<U, T> is `true`,(16.3) — is_constructible_v<U, Ts> is `true`,
(16.4) — is_copy_constructible_v<U> is `true`, and
(16.5) — is_default_constructible_v<Allocator> is `true`.
-?- Mandates: derived_from<U, T> is `true`.
-17- Effects: […]template<class U, class... Ts> constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, in_place_type_t<U>, Ts&&... ts);-18- Constraints:
(18.1) — is_same_v<remove_cvref_t<U>, U> is `true`,
(18.2) — derived_from<U, T> is `true`,(18.3) — is_constructible_v<U, Ts> is `true`, and
(18.4) — is_copy_constructible_v<U> is `true`.
-?- Mandates: derived_from<U, T> is `true`.
-19- Effects: […]template<class U, class I, class... Us> constexpr explicit polymorphic(in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);-20- Constraints:
(20.1) — is_same_v<remove_cvref_t<U>, U> is `true`,
(20.2) — derived_from<U, T> is `true`,(20.3) — is_constructible_v<U, initializer_list<I>&, Us...> is `true`,
(20.4) — is_copy_constructible_v<U> is `true`, and
(20.5) — is_default_constructible_v<Allocator> is `true`.
-?- Mandates: derived_from<U, T> is `true`.
-21- Effects: […]template<class U, class I, class... Us> constexpr explicit polymorphic(allocator_arg_t, const Allocator& a, in_place_type_t<U>, initializer_list<I> ilist, Us&&... us);-22- Constraints:
(22.1) — is_same_v<remove_cvref_t<U>, U> is `true`,
(22.2) — derived_from<U, T> is `true`,(22.3) — is_constructible_v<U, initializer_list<I>&, Us...> is `true`, and
(22.4) — is_copy_constructible_v<U> is `true`.
-?- Mandates: derived_from<U, T> is `true`.
-23- Effects: […]
The class templates indirect<T> and polymorphic<T> allow the template argument `T` to be an incomplete type.
Both classes can be instantiated when the type `T` is incomplete: constraints are written so that requirements on incomplete types are not evaluated at class instantiation time. For constructors with additional template parameters, there are currently constraints written on the potentially incomplete type `T` and the additional template parameters. Such constraints will not be evaluated at class instantiation time but could be explicitly evaluated in contexts where support for an incomplete `T` is required.template<typename U> class A { U u; public: A(const SomeType&) requires std::is_constructible_v<U, SomeType> { // […] } };
when `U` is indirect<T> or polymorphic<T> for some type `T`, the existence of the requires clause will require that `T` is a complete type for constraints on indirect or polymorphic to be evaluated.
Constraints on `T` should be converted to Mandates on `T` so that constraint evaluation does not require `T` to be a complete type.History | |||
---|---|---|---|
Date | User | Action | Args |
2025-08-23 13:40:52 | admin | set | messages: + msg14950 |
2025-08-20 00:00:00 | admin | create |