从成员函数指针获取方法的返回类型

问题描述 投票:0回答:3

我试图声明一个变量,使其类型与我有一个成员函数指针的成员函数的返回类型相同。

class Widget {
    public:
        std::chrono::milliseconds Foo();
};

例如,给定一个指向

fn
的成员函数指针
Widget::Foo
, 我如何声明一个变量
blah
以便它获得
Widget::Foo
的返回类型 (
std::chrono::milliseconds
)?

我从一篇博客文章中发现了一些有希望的指导,该文章使用

result_of
中的
<type_traits>
以及
decltype
,但我似乎无法让它发挥作用。

auto fn = &Widget::Foo;
Widget w;
std::result_of<decltype((w.*fn)())>::type blah;

这种方法对我来说很有意义,但 VC++ 2013 不喜欢它。

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

我不知道我是否做错了什么,或者这是否是 VC++ 尚未处理的事情(或两者兼而有之!)。我在错误消息中看到的唯一线索是

__cdecl
。调用约定不应该是
__thiscall
吗?

c++ type-traits pointer-to-member decltype
3个回答
20
投票
decltype((w.*fn)()) blah;

或者

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

1
投票

不知道为什么它适用于:

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

但我认为括号里应该是指向Widget的指针。因为第一个成员参数隐藏了'this',一个指向对象的指针

std::result_of<decltype(fn)(Widget*)>::type blah;
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

此外,我们无法创建抽象类的对象,因此如果 Widget 是一个抽象类并且其指针不在括号中,则代码将无法编译

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

编译错误:

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;//

0
投票

从 C++17 开始你可以使用

std::invoke_result
像这样:

std::invoke_result<fn,Widget>::type blah;
© www.soinside.com 2019 - 2024. All rights reserved.