ConvertibleTo prose does not match codeSection: 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
ConvertibleToconcept requiresana 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
testbe the invented function:To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types
FromandTo, and letfbe a function with no arguments and return typeadd_rvalue_reference_t<From>such thatf()is equality-preserving.FromandTomodelConvertibleTo<From, To>only if:
(2.1) —
Tois not an object or reference-to-object type, orstatic_cast<To>(f())is equal totest(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 byf()after either above expression is valid but unspecified (16.4.6.17 [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_toconcept requiresana 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
testbe the invented function:To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types
FromandTo, and letfbe a function with no arguments and return typeadd_rvalue_reference_t<From>such thatf()is equality-preserving.FromandTomodelconvertible_to<From, To>only if:
(2.1) —
Tois not an object or reference-to-object type, orstatic_cast<To>(f())is equal totest(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 byf()after either above expression is valid but unspecified (16.4.6.17 [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.
This wording is relative to N4835, and also resolves LWG 3151.
Modify 18.4.4 [concept.convertible] as indicated:
-1- The
convertible_toconcept for typesFromandTorequires an expressionEsuch thatdecltype((E))isadd_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
FromRbeadd_rvalue_reference_t<From>andtestbe the invented function:To test(FromR (&f)()) { return f(); }for some types
FromandTo, and letfbe a function with no arguments and return typeFromRsuch thatf()is equality-preserving.FromandTomodelconvertible_to<From, To>only if:
(2.1) —
Tois not an object or reference-to-object type, orstatic_cast<To>(f())is equal totest(f).(2.2) —
FromRis not a reference-to-object type, or
(2.2.1) — If
FromRis an rvalue reference to a non const-qualified type, the resulting state of the object referenced byf()after either above expression is valid but unspecified (16.4.6.17 [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
FromandToand an expressionEsuch thatdecltype((E))isadd_rvalue_reference_t<From>,convertible_to<From, To>Therequiresconvertible_toconceptEan expression of a particular type and value categoryto be both implicitly and explicitly convertible tosome othertypeTo. 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
FromRbeadd_rvalue_reference_t<From>andtestbe the invented function:To test(FromR (&f)()) { return f(); }for some types
FromandTo, and letfbe a function with no arguments and return typeFromRsuch thatf()is equality-preserving.FromandTomodelconvertible_to<From, To>only if:
(2.1) —
Tois not an object or reference-to-object type, orstatic_cast<To>(f())is equal totest(f).(2.2) —
FromRis not a reference-to-object type, or
(2.2.1) — If
FromRis an rvalue reference to a non const-qualified type, the resulting state of the object referenced byf()after either above expression is valid but unspecified (16.4.6.17 [lib.types.movedfrom]).(2.2.2) — Otherwise, the object referred to by
f()is not modified by either above expression.