c++type-traitspointer-to-memberdecltype

Get the return type of a method from a member function pointer


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?


Solution

  • decltype((w.*fn)()) blah;
    

    Or

    std::result_of<decltype(fn)(Widget)>::type blah;