This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
Section: 18.4.4 [concept.convertible] Status: C++20 Submitter: Hubert Tong Opened: 2019-03-05 Last modified: 2021-02-25
Priority: 1
View other active issues in [concept.convertible].
View all other issues in [concept.convertible].
View all issues with C++20 status.
Discussion:
The prose in N4800 subclause [concept.convertibleto] indicates that the requirement is for an expression of a particular type and value category to be both implicitly and explicitly convertible to some other type. However, for a type
struct A { A(const A&) = delete; };
ConvertibleTo<const A, A> would be false despite the following being okay:
const A f(); A test() { static_cast<A>(f()); return f(); }
[2019-03-15 Priority set to 1 after reflector discussion]
[2019-07-14 Tim adds PR based on discussion in 2019-07-09 LWG telecon]
Previous resolution [SUPERSEDED]:This wording is relative to N4820, and also resolves LWG 3151.
Modify [concept.convertibleto] as indicated:
-1- The ConvertibleTo concept requires
ana glvalue expression of a particular type and value category to be both implicitly and explicitly convertible to some other type. The implicit and explicit conversions are required to produce equal results.template<class From, class To> concept ConvertibleTo = is_convertible_v<From, To> && requires(add_rvalue_reference_t<From> (&f)()) { static_cast<To>(f()); };-2- Let test be the invented function:
To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types From and To, and let f be a function with no arguments and return type add_rvalue_reference_t<From> such that f() is equality-preserving. From and To model ConvertibleTo<From, To> only if:
(2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).
(2.2) — add_rvalue_reference_t<From> is not a reference-to-object type, or
(2.2.1) — If add_rvalue_reference_t<From> is an rvalue reference to a non const-qualified type, the resulting state of the object referenced by f() after either above expression is valid but unspecified (16.4.6.15 [lib.types.movedfrom]).
(2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.
[2019-09-23; Daniel adjusts wording to working draft changes]
Due to the concept renaming caused by P1754R1 the proposed wording is outdated and needs adjustments.
Previous resolution [SUPERSEDED]:This wording is relative to N4830, and also resolves LWG 3151.
Modify 18.4.4 [concept.convertible] as indicated:
-1- The convertible_to concept requires
ana glvalue expression of a particular type and value category to be both implicitly and explicitly convertible to some other type. The implicit and explicit conversions are required to produce equal results.template<class From, class To> concept convertible_to = is_convertible_v<From, To> && requires(add_rvalue_reference_t<From> (&f)()) { static_cast<To>(f()); };-2- Let test be the invented function:
To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types From and To, and let f be a function with no arguments and return type add_rvalue_reference_t<From> such that f() is equality-preserving. From and To model convertible_to<From, To> only if:
(2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).
(2.2) — add_rvalue_reference_t<From> is not a reference-to-object type, or
(2.2.1) — If add_rvalue_reference_t<From> is an rvalue reference to a non const-qualified type, the resulting state of the object referenced by f() after either above expression is valid but unspecified (16.4.6.15 [lib.types.movedfrom]).
(2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.
[2019-11-06 Tim updates PR based on discussion in Belfast LWG evening session]
"glvalue" is incorrect because we want to allow testing convertible_to<void, void>. It's also less than clear how the "expression" and "a particular type" in the first sentence correspond to the parameters of the concept.
Previous resolution [SUPERSEDED]:This wording is relative to N4835, and also resolves LWG 3151.
Modify 18.4.4 [concept.convertible] as indicated:
-1- The convertible_to concept for types From and To requires an expression E such that decltype((E)) is add_rvalue_reference_t<From>
of a particular type and value categoryto be both implicitly and explicitly convertible tosome other typeTo. The implicit and explicit conversions are required to produce equal results.template<class From, class To> concept convertible_to = is_convertible_v<From, To> && requires(add_rvalue_reference_t<From> (&f)()) { static_cast<To>(f()); };-2- Let FromR be add_rvalue_reference_t<From> and test be the invented function:
To test(FromR (&f)()) { return f(); }for some types From and To, and let f be a function with no arguments and return type FromR such that f() is equality-preserving. From and To model convertible_to<From, To> only if:
(2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).
(2.2) — FromR is not a reference-to-object type, or
(2.2.1) — If FromR is an rvalue reference to a non const-qualified type, the resulting state of the object referenced by f() after either above expression is valid but unspecified (16.4.6.15 [lib.types.movedfrom]).
(2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.
[2019-11-09 Tim rephrased first sentence based on discussion in Belfast LWG Saturday session]
[Status to Tentatively ready after Belfast LWG Saturday session]
Proposed resolution:
This wording is relative to N4835, and also resolves LWG 3151.
Modify 18.4.4 [concept.convertible] as indicated:
-1- Given types From and To and an expression E such that decltype((E)) is add_rvalue_reference_t<From>, convertible_to<From, To>
The convertible_to conceptrequires Ean expression of a particular type and value categoryto be both implicitly and explicitly convertible tosome othertype To. The implicit and explicit conversions are required to produce equal results.template<class From, class To> concept convertible_to = is_convertible_v<From, To> && requires(add_rvalue_reference_t<From> (&f)()) { static_cast<To>(f()); };-2- Let FromR be add_rvalue_reference_t<From> and test be the invented function:
To test(FromR (&f)()) { return f(); }for some types From and To, and let f be a function with no arguments and return type FromR such that f() is equality-preserving. From and To model convertible_to<From, To> only if:
(2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).
(2.2) — FromR is not a reference-to-object type, or
(2.2.1) — If FromR is an rvalue reference to a non const-qualified type, the resulting state of the object referenced by f() after either above expression is valid but unspecified (16.4.6.15 [lib.types.movedfrom]).
(2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.