Do not require reference_wrapper to support non-referenceable function types
Jonathan Wakely

Created on 2017-12-14.00:00:00, last changed 2019-03-16.13:34:20.


Date: 2019-03-16.13:34:20

Proposed resolution:

This wording is relative to N4800.

  1. Modify [refwrap] as indicated:

    -1- reference_wrapper<T> is a Cpp17CopyConstructible and Cpp17CopyAssignable wrapper around a reference to an object or function of type T. If reference_wrapper is instantiated with a non-referenceable type ([defns.referenceable]) as the argument for the template parameter T, the program is ill-formed.

    -2- reference_wrapper<T> is a trivially copyable type ([basic.types]).

    -3- The template parameter T of reference_wrapper may be an incomplete type.

Date: 2019-03-15.00:00:00

[ 2019-03-15; Daniel comments and provides revised wording ]

The current wording is now far behind the working draft and a synchronization is therefore recommended. In particular, with the acceptance of P0357R1, the specification of reference_wrapper has no longer any weak result type. Second, I would like to concur with a remark from Tomasz to change the wording to replace the undefined behavior by an ill-formed program instead, because every attempt to instantiate the definition of reference_wrapper will instantiate its member declarations, and this would cause the program to become ill-formed anyway because of the illegal formation of references to non-referenceable function types for member functions such as T& get() const noexcept.

As concrete wording suggestion I would recommend wording that ensures that an ill-formed program is only required when a specialization of reference_wrapper is instantiated, because in the absence of a constrained template parameter we shouldn't require implementations to diagnose even forming the name of a reference_wrapper specialization such as in the following example:

using X = reference_wrapper<int() const>;

The wording below does not take advantage of a Mandates: element to prevent a dependency on LWG 3193 and because such an element is rarely used to specify class templates. If the committee wishes to use such an element, the equivalent wording would be:

Mandates: reference_wrapper is instantiated with a referenceable type ([defns.referenceable]) as the argument for the template parameter T.

Date: 2019-03-16.13:34:20

[ 2018-01; Priority set to 3 after mailing list discussion ]

Previous resolution [SUPERSEDED]:

This wording is relative to N4713.

  1. Modify [refwrap] as indicated:

    -1- reference_wrapper<T> is a CopyConstructible and CopyAssignable wrapper around a reference to an object or function of type T. T shall be a referenceable type ([defns.referenceable]) that is not a reference type.

    -2- reference_wrapper<T> shall be a trivially copyable type ([basic.types]).

Date: 2017-12-14.00:00:00

[refwrap] says that reference_wrapper<T> is a "wrapper around a reference to an object or function of type T" but this doesn't actually constrain it, and doesn't forbid non-referenceable function types like int() const.

There is no way to construct a reference_wrapper<int() const> but implementations are required to provide partial specializations for functions with cv-qualifiers and ref-qualifiers in order to define a nested result_type. It should be undefined to instantiate reference_wrapper<T> with a non-referenceable type, or with a reference type (since references to references are not possible). Making it undefined (rather than ill-formed or unspecified) means implementations are not required to diagnose such invalid specializations, but also don't have to go to the effort of supporting weak result types etc.

Date User Action Args
2019-03-16 13:34:20adminsetmessages: + msg10354
2018-01-29 17:21:16adminsetmessages: + msg9661
2017-12-16 10:17:37adminsetmessages: + msg9593
2017-12-14 00:00:00admincreate