我试图声明一个变量,使其类型与我有一个成员函数指针的成员函数的返回类型相同。
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
吗?
decltype((w.*fn)()) blah;
或者
std::result_of<decltype(fn)(Widget)>::type blah;
不知道为什么它适用于:
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;//
从 C++17 开始你可以使用
std::invoke_result
像这样:
std::invoke_result<fn,Widget>::type blah;