Don Pedro Don Pedro - 8 days ago 6
C++ Question

How to use decltype with member functions

I'm trying to use decltype on member functions in Visual Studio 2012. I've stumbled upon a peculiarity and I'm wondering if this is intention or if it is a compiler bug. Consider (just a code snippet without meaning to show my point):

struct Test { int f() {return 0;} } T;
std::integral_constant<decltype(T.f()), 5>;
std::integral_constant<decltype(&Test::f), 5>; // error C2440


While the second line compiles, the third gives an error C2440: 'specialization' : cannot convert from 'int' to 'int (__thiscall Test::*)(void)'

How come decltype on an instanciated call to a function yields its return type (this is what I am expecting), however trying to do the same without any member involved does yield a member function pointer? If this is the intended behavior, what is the reasoning behind it? How would I denote that I'm requesting the return type of a member function, without actually having an instance at hand? Of course I could do it the dirty way:

std::integral_constant<decltype(((Test*)nullptr)->f()), 5>;


But unquestionable this is pretty, pretty ugly and there should be a clean, straightforward C++ way to express this.

Answer

&Test::f does not call the member function Test::f. Instead, it takes the address of the member function and results in a pointer to member function, which is of type int Test::*().

In order to do what you want, you should use std::declval. The correct syntax is

std::integral_constant<decltype(std::declval<Test>().f()), 5>
Comments