This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 1270. `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 type `Fn` and values `t1, t2, ..., tN` of types T1, T2, ..., TN in `ArgTypes`, respectively, the type member is the result type of the expression `fn(t1, t2, ...,tN)`. The values `ti` are lvalues when the corresponding type `Ti` 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 of `T`.
> `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 type `decltype(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]