reference_wrapper
to support non-referenceable function typesSection: 22.10.6 [refwrap] Status: New Submitter: Jonathan Wakely Opened: 2017-12-14 Last modified: 2020-09-06
Priority: 3
View all other issues in [refwrap].
View all issues with New status.
Discussion:
[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
.
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.
[2018-01; Priority set to 3 after mailing list discussion]
Previous resolution [SUPERSEDED]:
This wording is relative to N4713.
Modify 22.10.6 [refwrap] as indicated:
-1-
-2-reference_wrapper<T>
is aCopyConstructible
andCopyAssignable
wrapper around a reference to an object or function of typeT
.T
shall be a referenceable type (3.44 [defns.referenceable]) that is not a reference type.reference_wrapper<T>
shall be a trivially copyable type (6.8 [basic.types]).
[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
.
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 (3.44 [defns.referenceable]) as the argument for the template parameterT
.
Proposed resolution:
This wording is relative to N4800.
Modify 22.10.6 [refwrap] as indicated:
-1-
-2-reference_wrapper<T>
is a Cpp17CopyConstructible and Cpp17CopyAssignable wrapper around a reference to an object or function of typeT
. Ifreference_wrapper
is instantiated with a non-referenceable type (3.44 [defns.referenceable]) as the argument for the template parameterT
, the program is ill-formed.reference_wrapper<T>
is a trivially copyable type (6.8 [basic.types]). -3- The template parameterT
ofreference_wrapper
may be an incomplete type.