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.
&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>