ben*_*305 8 c++ function-object
Run Code Online (Sandbox Code Playgroud)// Fallback, anything with an operator() template <typename T> struct function_traits : public function_traits<decltype(&T::operator())> > { };
这里是什么T::operator()意思?
这是来自 pytorch 的代码。
Tob*_*ght 11
&T::operator()是一个指向成员函数的指针。typename T在本例中,它是指向的成员函数的指针operator()。
为了给它一个具体的基础,请考虑以下的最小定义T:
struct T
{
int operator()(int x) { return x * 2; }
};
Run Code Online (Sandbox Code Playgroud)
我们可以将指向成员函数的指针保存在变量中:
int (T::*pmf)(int);
pmf = &T::operator();
Run Code Online (Sandbox Code Playgroud)
我们可以称之为:
T object;
int four = (object.*pmf)(2);
Run Code Online (Sandbox Code Playgroud)
请注意,我是FunctionTraits的作者。您是否已经熟悉“函数对象”,又名“函子”。如果需要的话,可能不会先用谷歌搜索(另请参阅“Motti”的回复)。我会继续说,就好像您对此没有太多经验一样。
在您发布的代码中,“T”旨在成为一个函子,即声明了非静态成员函数“ T::operator() ”的类。声明“ function_traits ”结构的目的是检索后一个成员函数的函数特征。IOW,给定任何类或结构,如下所示:
class Whatever
{
public:
float operator()(int);
};
Run Code Online (Sandbox Code Playgroud)
首先请注意,“ Whatever ”是一个声明一个名为“ operator() ”的非静态成员函数的类,因此“ Whatever ”根据定义是一个函子(因为它是一个声明非静态“ operator() ”成员的类 -它的签名无关)。请注意,“ operator() ”仅允许您使用“Whatever”的实例来调用此成员,就好像它是一个函数一样。因此,您可以这样做:
Whatever whatever;
whatever(3);
Run Code Online (Sandbox Code Playgroud)
它调用“ operator() ”成员。我不会在这里讨论这种语法的用法,因为其他地方有很多关于这个主题的信息。现在可以说,对“ whatever(3) ”的调用只是允许您通过使用所见的函数调用语法来调用名为“ operator() ”的成员函数,就好像“ whatever ”是一个函数一样。然而,这只是语法糖:
whatever.operator()(3);
Run Code Online (Sandbox Code Playgroud)
您甚至可以这样调用它,因为它与任何其他非静态成员函数调用没有什么不同,除了函数名称是“ operator() ”,这是编译器识别的特殊名称(称为函数调用运算符)。但是,除了使用函数调用语法来调用它的能力之外,它仍然与任何其他成员函数没有什么不同。因此,它可以采用您想要的任何参数(上例中的“int”),或返回任何类型(上例中的“float”),或者是“const”或“noexcept”等。
因此,您发布的“ function_traits ”结构的目的是检索该成员函数的函数特征。IOW,如果你这样做:
using WhateverTraits = function_traits<Whatever>;
Run Code Online (Sandbox Code Playgroud)
“ function_traits ”专门针对函子(“ Whatever ”),因此它将存储成员函数“ Whatever::operator() ”的特征。它通过简单地继承“ function_traits<decltype(&T::operator()) > 来实现这一点,这只是采用非静态成员函数指针类型的“ function_traits ”的特化。对“ decltype(&T::operator() 的调用” )) “只是将成员“ T::operator() ”的类型传递给后一个特化,因此在上面的情况下,它传递了非静态成员函数“ Whatever::operator() ”的类型。进一步分解它,调用:
&Whatever::operator()
Run Code Online (Sandbox Code Playgroud)
返回指向成员函数“Whatever::operator()”的指针,因此在本例中,它是指向采用“int”参数并返回“float”的非静态成员函数的指针。致电:
decltype(&Whatever::operator())
Run Code Online (Sandbox Code Playgroud)
然后简单地产生这个指针的类型:
float (Whatever::*)(int)
Run Code Online (Sandbox Code Playgroud)
然后该类型作为模板参数传递给“function_traits”基类。通过这样做,它通过继承采用成员函数指针类型的专业化来委派检索仿函数“T”的函数特征的工作,在本例中是成员函数指针类型“ &T:: operator() ”(因此“ &Whatever: :operator() " 在上面的例子中,因此是上面的指针类型)。因此,您可以获取该成员函数的特征。
这只是通过继承非静态成员函数的特化来实现函子的“ function_traits ”的快速而简单的方法。
我希望这有帮助。