result_of
should be moved to <type_traits>
Section: 99 [func.ret] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-11-19 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [func.ret].
View all issues with C++11 status.
Discussion:
Addresses UK 198
NB Comment: UK-198 makes this request among others. It refers to a more detailed issue that BSI did not manage to submit by the CD1 ballot deadline though.
result_of
is essentially a metafunction to return the type of an
expression, and belongs with the other library metafunctions in
<type_traits>
rather than lurking in <functional>
.
The current definition in <functional>
made sense when
result_of
was nothing more than a protocol to enable several components
in <functional>
to provide their own result types, but it has
become a more general tool. For instance, result_of
is now used in the
threading and futures components.
Now that <type_traits>
is a required header for free-standing
implementations it will be much more noticeable (in such environments) that a
particularly useful trait is missing, unless that implementation also chooses to
offer <functional>
as an extension.
The simplest proposal is to simply move the wording (editorial direction below) although a more consistent form for type_traits would reformat this as a table.
Following the acceptance of 1255, result_of
now
depends on the declval
function template, tentatively provided
in <utility>
which is not (yet) required of a
free-standing implementation.
This dependency is less of an issue when result_of
continues to
live in <functional>
.
Personally, I would prefer to clean up the dependencies so both
result_of
and declval
are available in a free-standing
implementation, but that would require slightly more work than suggested
here. A minimal tweak would be to require <utility>
in a
free-standing implementation, although there are a couple of subtle
issues with make_pair
, which uses reference_wrapper
in
its protocol and that is much harder to separate cleanly from
<functional>
.
An alternative would be to enact the other half of
N2979
and create a new minimal header for the new C++0x library facilities to
be added to the freestanding requirements (plus swap
.)
I have a mild preference for the latter, although there are clearly
reasons to consider better library support for free-standing in general,
and adding the whole of <utility>
could be considered a step in that
direction. See NB comment
JP-23
for other suggestions (array
, ratio
)
[ 2010-01-27 Beman updated wording. ]
The original wording is preserved here:
Move 99 [func.ret] to a heading below 21 [meta]. Note that in principle we should not change the tag, although this is a new tag for 0x. If it has been stable since TR1 it is clearly immutable though.
This wording should obviously adopt any other changes currently in (Tentatively) Ready status that touch this wording, such as 1255.
[ 2010-02-09 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]
Proposed resolution:
From Function objects 22.10 [function.objects], Header <functional>
synopsis, remove:
// 20.7.4 result_of: template <class> class result_of; // undefined template <class F, class... Args> class result_of<F(ArgTypes...)>;
Remove Function object return types 99 [func.ret] in its entirety. This sub-section reads:
namespace std { template <class> class result_of; // undefined template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)> { public : // types typedef see below type; }; }Given an rvalue
fn
of typeFn
and valuest1, t2, ..., tN
of types T1, T2, ..., TN inArgTypes
, respectively, the type member is the result type of the expressionfn(t1, t2, ...,tN)
. The valuesti
are lvalues when the corresponding typeTi
is an lvalue-reference type, and rvalues otherwise.
To Header <type_traits> synopsis 21.3.3 [meta.type.synop], add at the indicated location:
template <class T> struct underlying_type; template <class T> struct result_of; // not defined template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
To Other transformations 21.3.8.7 [meta.trans.other], Table 51 — Other transformations, add:
Template Condition Comments template <class T>
struct underlying_type;T
shall be an enumeration type (7.2)The member typedef type
shall name the underlying type ofT
.template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
Fn
shall be a function object type 22.10 [function.objects], reference to function, or reference to function object type.decltype(declval<Fn>()(declval<ArgTypes>()...))
shall be well formed.The member typedef type
shall name the typedecltype(declval<Fn>()(declval<ArgTypes>()...))
.
At the end of Other transformations 21.3.8.7 [meta.trans.other] add:
[Example: Given these definitions:
typedef bool(&PF1)(); typedef short(*PF2)(long); struct S { operator PF2() const; double operator()(char, int&); };the following assertions will hold:
static_assert(std::is_same<std::result_of<S(int)>::type, short>::value, "Error!"); static_assert(std::is_same<std::result_of<S&(unsigned char, int&)>::type, double>::value, "Error!"); static_assert(std::is_same<std::result_of<PF1()>::type, bool>::value, "Error!");— end example]