When do you use function objects in C++?

戏子无情 提交于 2019-11-26 21:20:19

问题


I see function objects used often together with STL algorithms. Did function objects came about because of these algorithms? When do you use a function object in C++? What is its benefits?


回答1:


As said jdv, functors are used instead of function pointers, that are harder to optimize and inline for the compiler; moreover, a fundamental advantage of functors is that they can easily preserve a state between calls to them1, so they can work differently depending on the other times they have been called, keep track somehow of the parameters they have used, ...

For example, if you want to sum all the elements in two containers of ints you may do something like this:

struct
{
    int sum;
    void operator()(int element) { sum+=element; }
} functor;
functor.sum=0;
functor = std::for_each(your_first_container.begin(), your_first_container.end(), functor);
functor = std::for_each(your_second_container.begin(), your_second_container.end(), functor);
std::cout<<"The sum of all the elements is: "<<functor.sum<<std::endl;

  1. Actually, as R Samuel Klatchko pointed out below, they can support multiple independent states, one for each functor instance:
    A slightly more precise statement is that functors can support multiple independent states (functions can support a single state via statics/globals which is neither thread-safe nor reentrant).
    Functors enables you to use even more complicated states, for example a shared state (static fields) and a private state (instance fields). However this further flexibility is rarely used.



回答2:


Function objects (functors) are typically used instead of function pointers. Function pointers have the problem that the compiler typically passes them as raw pointers, which makes it hard for the compiler to inline the code later. And they're easier to give parameters.




回答3:


Function objects were designed to allow a strong layer of abstraction over STL, and in that regard they are great.

However, I prefer to use boost::bind and bind a function to the STL algorithms instead -- usually (although not in cases where the object has a state) that seems a more elegant solution.

std::for_each( callback.begin(), callback.end(), 
    boost::bind(&Callback::call(),_1) 
);

Also, another upcoming alternative are lambda's in C++0x (example shamelessly stolen from Wikipedia):

std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
  total += x;
});
std::cout << total;

Notice that due to closures, they do not have the restriction of bind about not having a state.




回答4:


A function object is a function that is also an object, i.e. it has state. Normal functions generally do not have state. They may emulate having state by accessing global variables, but then the state is shared across all invocations.




回答5:


The idea of encapsulating a function as an object dates back to Lisp and Smalltalk. The C++ idea of functor was a chapter in Jim Coplien's book Advanced C++ Programming Styles and Idioms in 1991. STL used the idiom and further popularized it.




回答6:


I can't say why they came about - possibly simply because they could!

When do you use a functor? Consider that a functor is just moving the code you'd normally put in a loop into the operator() of a class, they're not that much different from just calling a function in a while loop... except, by using them you allow the compiler to inline the code and you can also pass a pre-constructed object instead, that you've constructed with some state. That latter point makes them very powerful.

Compare the sort algorithm with the CRTs qsort call. They do the same thing, only do it quite differently.




回答7:


This article has a great in-depth look at function objects, and how it can make code much more powerful, and cleaner too.



来源:https://stackoverflow.com/questions/2351437/when-do-you-use-function-objects-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!