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
ConvertibleTo
concept 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
test
be the invented function:To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types
From
andTo
, and letf
be a function with no arguments and return typeadd_rvalue_reference_t<From>
such thatf()
is equality-preserving.From
andTo
modelConvertibleTo<From, To>
only if:
(2.1) —
To
is 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.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 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
test
be the invented function:To test(add_rvalue_reference_t<From> (&f)()) { return f(); }for some types
From
andTo
, and letf
be a function with no arguments and return typeadd_rvalue_reference_t<From>
such thatf()
is equality-preserving.From
andTo
modelconvertible_to<From, To>
only if:
(2.1) —
To
is 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.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.
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 typesFrom
andTo
requires an expressionE
such 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
FromR
beadd_rvalue_reference_t<From>
andtest
be the invented function:To test(FromR (&f)()) { return f(); }for some types
From
andTo
, and letf
be a function with no arguments and return typeFromR
such thatf()
is equality-preserving.From
andTo
modelconvertible_to<From, To>
only if:
(2.1) —
To
is not an object or reference-to-object type, orstatic_cast<To>(f())
is equal totest(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 byf()
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
andTo
and an expressionE
such thatdecltype((E))
isadd_rvalue_reference_t<From>
,convertible_to<From, To>
Therequiresconvertible_to
conceptE
an 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
FromR
beadd_rvalue_reference_t<From>
andtest
be the invented function:To test(FromR (&f)()) { return f(); }for some types
From
andTo
, and letf
be a function with no arguments and return typeFromR
such thatf()
is equality-preserving.From
andTo
modelconvertible_to<From, To>
only if:
(2.1) —
To
is not an object or reference-to-object type, orstatic_cast<To>(f())
is equal totest(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 byf()
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.