I'm trying to declare a variable so that its type is the same as the return type of a member function to which I have a member function pointer.
class Widget {
public:
std::chrono::milliseconds Foo();
};
For example, given a member function pointer fn
which points to Widget::Foo
,
how would I declare a variable blah
so that it gets Widget::Foo
's return type (std::chrono::milliseconds
)?
I found some promising guidance from a blog post that uses result_of
from <type_traits>
along with decltype
, but I can't seem to get it to work.
auto fn = &Widget::Foo;
Widget w;
std::result_of<decltype((w.*fn)())>::type blah;
This approach makes sense to me, but VC++ 2013 doesn't like it.
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap(58): error C2064: term does not evaluate to a function taking 0 arguments
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,>' being compiled
with
[
_Fty=std::chrono::milliseconds (__cdecl Widget::* )(void)
]
scratch.cpp(24) : see reference to class template instantiation 'std::result_of<std::chrono::milliseconds (__cdecl Widget::* (void))(void)>' being compiled
I don't know if I'm doing something wrong or if this is something that VC++ doesn't handle yet (or both!). The only clue I see in the error message is the __cdecl
. Shouldn't the calling convention be __thiscall
?
Return type using decltype To get the return type of foo , we simply use the following: using t = decltype(foo()); t now contains the return type.
You can use pointers to member functions in the same manner as pointers to functions. You can compare pointers to member functions, assign values to them, and use them to call member functions.
Using a pointer-to-member-function to call a function Calling the member function on an object using a pointer-to-member-function result = (object. *pointer_name)(arguments); or calling with a pointer to the object result = (object_ptr->*pointer_name)(arguments);
To access a member function by pointer, we have to declare a pointer to the object and initialize it (by creating the memory at runtime, yes! We can use new keyboard for this). The second step, use arrow operator -> to access the member function using the pointer to the object.
decltype((w.*fn)()) blah;
Or
std::result_of<decltype(fn)(Widget)>::type blah;
dont' know why works with
std::result_of<decltype(fn)(Widget)>::type blah;
But I think in brackets should be a pointer to Widget. Because the first member parameter is hidden 'this', a pointer to object
std::result_of<decltype(fn)(Widget*)>::type blah;
#include <iostream>
using namespace std;
class Widget
{
public:
virtual int foo() = 0;
};
int Widget::foo()
{}
int main() {
// your code goes here
auto fn = &Widget::foo;
std::result_of<decltype(fn)(Widget*)>::type blah = 5;
std::cout << blah;
return 0;
}
output:
5
Also we can't create objects of abstract classes, so code won't compile, if Widget will be an abstract class and not its pointer will be in the brackets
std::result_of<decltype(fn)(Widget)>::type blah = 5;
compile error:
error: cannot declare parameter to be of abstract type 'Widget'
std::result_of<decltype(fn)(Widget)>::type blah = 5;//
error: incomplete type 'std::result_of<int (Widget::*(Widget))()>' used in nested name specifier
std::result_of<decltype(fn)(Widget)>::type blah = 5;//
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With