函数对象(通常称为functors)只是一个可以像函数一样工作的对象。例如,如果您想要一个在调用之间跟踪某事的函数,这很有用。
要像函数一样使用对象,您需要能够调用它,如下所示:
reallyAnObject(some, args);
您可以通过为您的班级重载operator() 来实现这一点。
<functional> 标头提供了各种有用的工具来帮助您制作函数对象。
这是一个非常简单的例子:
struct Functor {
void operator() (int i)
{
std::cout << "Really an object. Called with " << i << '\n';
}
};
int main() {
Functor f;
// prints "Really an object. Called with 1"
f(1);
}
现在我想一个更有用的功能可能是将一大堆数字打印到同一个流中(尽管仍然很做作):
struct Printer {
std::ostream& os_;
Printer (std::ostream& os) : os_(os) {}
void operator() (int i)
{
os << i;
}
};
int main() {
// prints "12" to stdout
Printer p {std::cout};
p(1);
p(2);
// prints "34" to stderr
Printer p2 {std::cerr};
p2(3);
p2(4);
}
更复杂的示例通常有助于与标准 <algorithm>s 进行交互。
<functional> 标头提供了许多人们经常自己编写的有用信息,例如 std::plus、std::greater、std::unary_negate。它还提供std::function 和std::bind,但我暂时远离这些,它们有点棘手。