在阅读一些代码时,我遇到了这个功能。我很难理解函数的签名。在我能够制作以下代码的头部或尾部之前,我需要知道的是什么?
我一直在使用C ++一段时间。我知道模板,函数指针是什么。但是,我无法弄清楚T::*
可能意味着什么,以_Defer
开头的行在语义上意味着什么。
此外,该功能的第一行似乎非常令人生畏。在尝试重新评估此代码之前,是否有一些我可以阅读的资源?
template <typename T>
_Defer<void(*(PID<T>, void (T::*)(void)))
(const PID<T>&, void (T::*)(void))>
defer(const PID<T>& pid, void (T::*method)(void))
{
void (*dispatch)(const PID<T>&, void (T::*)(void)) =
&process::template dispatch<T>;
return std::tr1::bind(dispatch, pid, method);
}
来源:https://github.com/3rdparty/libprocess/blob/master/include/process/defer.hpp
答案 0 :(得分:5)
这可能有助于澄清一些事情:
template<typename T>
using VoidPMemberFn = void(T::*)(); // Pointer to member function of T
// that accepts no arguments and
// returns nothing.
template<typename T>
using DeferResultType = void (*)(const PID<T> &, VoidPMemberFn<T>);
template<typename T>
using DeferSignatureType = DeferResultType<T>(PID<T>, VoidPMemberFn<T>);
template<typename T>
_Defer<DeferSignatureType<T>> defer(const PID<T> &pid, VoidPMemberFn<T> method)
{
// Stuff...
}
修改强>
这可能有助于澄清_Defer
模板中意大利面的含义,以及它与上述内容的关系:
void(* (PID<T>, void (T::*)(void)) )(const PID<T>&, void (T::*)(void))
^-+^-^ ^-------------------------^ ^-------------+------------------^
| argument list |
| |
+-----------------------------------------------+
return type: void(*)(const PID<T> &, void(T::*)(void))
这会创建一个“签名”,就像std::function
一样(例如std::function<int(float)>
)。
更多例子:
using sig = int(float);
sig gn; // Same as: "int gn(float)", a function declaration
int fn(float x)
{return (int)x;}
int main(int argc, char **argv)
{
// pointer to a function with signature "sig"
sig *pfn = &fn;
return 0;
}
int gn(float x)
{return (int)(x*x);}
答案 1 :(得分:0)
这是非标准的非便携式代码,因此很难为人类解码。返回类型
_Defer<void(*(PID<T>, void (T::*)(void)))(const PID<T>&, void (T::*)(void))>
是包含在某些标头中定义的某些类模板_Defer
的特化。这是在defube的答案中解释的。
但是,_Defer<>
不是std
库规范的一部分,因此以这种方式使用它会使代码不可移植,因此符合非标准。使用std::tr1::bind
代替std::bind
也是如此。
我猜你的函数的C ++ 14等价只是
template <typename T>
auto defer(const PID<T>& pid, void (T::*method)())
{
auto dispatch = &process::template dispatch<T>;
return std::bind(dispatch, pid, method);
}
其中process
必须是某个类(或基类,如果defer
是成员函数),并且具有静态模板成员方法dispatch
。因此,defer()
返回一些函数对象(参见documentation for std::bind
)以便稍后调用。
请注意,标准的返回类型std::bind
未指定,因此auto
(或将其打包成std::function
)是唯一的可移植方式处理它。