Title
ConvertibleTo prose does not match code
Status
c++20
Section
[concept.convertible]
Submitter
Hubert Tong

Created on 2019-03-05.00:00:00 last changed 46 months ago

Messages

Date: 2020-01-05.16:32:39

Proposed resolution:

This wording is relative to N4835, and also resolves LWG 3151.

  1. Modify [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 concept requires E an expression of a particular type and value category to be both implicitly and explicitly convertible to some other type 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:

    1. (2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).

    2. (2.2) — FromR is not a reference-to-object type, or

      1. (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 ([lib.types.movedfrom]).

      2. (2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.

Date: 2020-01-05.16:32:39

[ Status to Tentatively ready after Belfast LWG Saturday session ]

Date: 2019-11-09.00:00:00

[ 2019-11-09 Tim rephrased first sentence based on discussion in Belfast LWG Saturday session ]

Date: 2019-11-06.00:00:00

[ 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.

  1. Modify [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 category to be both implicitly and explicitly convertible to some other type 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:

    1. (2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).

    2. (2.2) — FromR is not a reference-to-object type, or

      1. (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 ([lib.types.movedfrom]).

      2. (2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.

Date: 2019-09-15.00:00:00

[ 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.

  1. Modify [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:

    1. (2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).

    2. (2.2) — add_rvalue_reference_t<From> is not a reference-to-object type, or

      1. (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 ([lib.types.movedfrom]).

      2. (2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.

Date: 2019-07-14.00:00:00

[ 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.

  1. 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:

    1. (2.1) — To is not an object or reference-to-object type, or static_cast<To>(f()) is equal to test(f).

    2. (2.2) — add_rvalue_reference_t<From> is not a reference-to-object type, or

      1. (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 ([lib.types.movedfrom]).

      2. (2.2.2) — Otherwise, the object referred to by f() is not modified by either above expression.

Date: 2019-03-15.00:00:00

[ 2019-03-15 Priority set to 1 after reflector discussion ]

Date: 2019-03-05.00:00:00

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();
}
History
Date User Action Args
2021-02-25 10:48:01adminsetstatus: wp -> c++20
2020-02-24 16:02:59adminsetstatus: voting -> wp
2020-01-17 04:54:50adminsetstatus: ready -> voting
2020-01-05 16:32:39adminsetmessages: + msg10912
2020-01-05 16:32:39adminsetstatus: new -> ready
2019-11-09 15:36:33adminsetmessages: + msg10810
2019-11-06 22:59:06adminsetmessages: + msg10769
2019-09-23 16:43:45adminsetmessages: + msg10663
2019-07-15 01:17:20adminsetmessages: + msg10482
2019-07-15 01:17:20adminsetmessages: + msg10481
2019-03-15 22:23:04adminsetmessages: + msg10352
2019-03-05 00:00:00admincreate