Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

question wrt std::result_of

27 views
Skip to first unread message

Doug Mika

unread,
Aug 21, 2015, 3:12:15 PM8/21/15
to
Hi, why must I write:
std::result_of<decltype(fn)&(int)>::type b; //what is the & for?
and why can't I write this instead:
std::result_of<fn(int))>::type b; //what is wrong with this?
in my program:
// result_of example
#include <iostream>
#include <type_traits>

int fn(int a) {return a;} // function

int main() {
int a=3;
//std::result_of<fn(int))>::type b;
std::result_of<decltype(fn)&(int)>::type b;
b=5;
std::cout<<b<<std::endl;
return 0;
}

Richard

unread,
Aug 21, 2015, 4:44:09 PM8/21/15
to
[Please do not mail me a copy of your followup]

Doug Mika <doug...@gmail.com> spake the secret code
<4600f7ab-69d2-4674...@googlegroups.com> thusly:

>Hi, why must I write:
> std::result_of<decltype(fn)&(int)>::type b; //what is the & for?
>and why can't I write this instead:
> std::result_of<fn(int))>::type b; //what is wrong with this?

fn is not a type, it is an identifier.

Use int(int)

>in my program:
>// result_of example
>#include <iostream>
>#include <type_traits>
>
>int fn(int a) {return a;} // function
>
>int main() {
> int a=3;
> //std::result_of<fn(int))>::type b;
> std::result_of<decltype(fn)&(int)>::type b;
> b=5;
> std::cout<<b<<std::endl;
> return 0;
>}


--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Alf P. Steinbach

unread,
Aug 21, 2015, 6:48:35 PM8/21/15
to
On 21.08.2015 21:11, Doug Mika wrote:
> Hi, why must I write:
> std::result_of<decltype(fn)&(int)>::type b; //what is the & for?
> and why can't I write this instead:
> std::result_of<fn(int))>::type b; //what is wrong with this?

Well, first off, it's self-inflicted pain to use `result_of` directly
here. Instead write just

function<decltype(fn)>::result_type b;

where `function` is `std::function`.

You need the `decltype` to get the /type/ of the function `fn`.

With direct use of `result_of` the type that you supply is a
construction that communicates two things simultaneously to `result_of`:

* the full function type, or more generally a /callable/ type, that
you're interested in result type of, call that A, and

* the argument types that it should be regarded as called with, call
them B1, B2, ... Bn,

Typically you communicate this as A*(B1, B2, ... Bn), which is the type
of a function returning A* and taking arguments B1, B2 ... Bn. In your
code you instead used A&(B1, B2, ... Bn). `result_of` accepts both
variants, but A(B1, B2, ... Bn) can't be used, because functions are not
copyable or movable; you can't have a function returning a function.

I don't know why it's done that way for `result_of`. It's inordinately
complicated and just hackish, it doesn't make much sense as client code
interface, and as `std::function` proves it's not necessary. I suspect
that it's due to some internal requirements in early Boost library code.


> in my program:
> // result_of example
> #include <iostream>
> #include <type_traits>
>
> int fn(int a) {return a;} // function
>
> int main() {
> int a=3;
> //std::result_of<fn(int))>::type b;
> std::result_of<decltype(fn)&(int)>::type b;
> b=5;
> std::cout<<b<<std::endl;
> return 0;
> }
>

Cheers & hth.,

- Alf

Doug Mika

unread,
Aug 21, 2015, 8:12:30 PM8/21/15
to
My function fn was:
int fn(int a) {return a;} // function

and if I could cout the decltype(fn), would it be something as follows:
int*(int)? Or is the function type merely it's return type?

Alf P. Steinbach

unread,
Aug 21, 2015, 8:23:58 PM8/21/15
to
On 22.08.2015 02:12, Doug Mika wrote:
> My function fn was:
> int fn(int a) {return a;} // function
>
> and if I could cout the decltype(fn), would it be something as follows:
> int*(int)?

Just `int(int)`. With the * (which would be written `int(*)(int)`) you'd
have a function pointer type.

And yes you can display a representation of the type. Just include the
`<typeinfo>` header and do

cout << typeid( fn ) << endl;

With Visual C++ you get a readable representation by default. With g++
you get a pretty unreadable compact result, but that can be fixed via
some compiler-specific functionality (I'd have to google it again,
sorry). With clang I'm not sure, but it's probably just like g++,
because clang was designed as a drop-in replacement for g++.
Correspondingly, the Intel compiler, IIRC designed as a drop in
replacement for Visual C++, is probably just like Visual C++. Summing
up, the result and how to fix-if-necessary depends on the compiler.


> Or is the function type merely it's return type?

No, the type is the full type, namely result and argument types. The
/signature/ is just the arguments, that is, the signature is the
function type without the result type. The signature is a useful concept
because overload resolution in C++ ignores the result type.

02xiaoma

unread,
Aug 21, 2015, 10:39:48 PM8/21/15
to
在 2015年8月22日星期六 UTC+8上午3:12:15,Doug Mika写道:
you can write like this :
std::result_of<decltype(fn)*(int)>::type b;

or you can write like this:
int(*func)(int);
func = fn;
std::result_of<decltype(func)(int)>::type b;

from MSDN:

The template class defines its member type as a synonym for the return type of a function call described by its template argument Ty. The template argument must be of the form Fty(T1, T2, ..., TN), where Fty is a callable type. The template determines the return type according to the first of the following rules that applies:
if Fty is a pointer to function type R(*)(U1, U2, ..., UN) the return type is R;
if Fty is a reference to function type R(&)(U1, U2, ..., UN) the return type is R;
...

if you really want to know what happens, you can go to look at the what is in the STL.

be happy
0 new messages