Related
I'd like to reduce amount of syntax required to refer to a function and was wondering if there was a way to do something like:
(NOT COMPILABLE)
using pushToLastUsed = mSomeLongStackFIFOObject.push_back;
// or
auto pushToLastUsed = mSomeLongStackFIFOObject.push_back;
then I could to something like:
pushToLastUsed(10);
instead of:
mSomeLongStackFIFOObject.push_back(10);
Of course I could make a macro like:
#define pushToLastUsed mSomeLongStackFIFOObject.push_back
// some code using it here
#undef pushToLastUsed
but I'd prefer not to use macros.
One solution might be to use a lambda expression to capture the function call into a callable object :
#include <vector>
void foo(std::vector<int> & bar)
{
auto pushToLastUsed = [&bar](int index) {
bar.push_back(index);
};
pushToLastUsed(10);
}
Though in my opinion there is very little to gain from doing this, even if you replace bar with a very long identifier.
My first idea was something along the line of the other answer. On a second read of your question I understand that it is mainly the long name of the object that you want to avoid to repeat. Hiding a call to a standard function should be done with care as its main effect is to obfuscate your code. Everybody knows what push_back does, but even you will likely forget what exactly pushToLastUse does. A different option is to alias only the mSomeLongStackFIFOObject with a shorter name as in
auto& short_name = mSomeLongStackFIFIObject;
short_name.push_back(10);
When you're writing mSomeLongStackFIFOObject.push_back(10); you're actually calling SomeLongStackFIFOClass::push_back(&mSomeLongStackFIFOObject, 10);
One option is to do:
auto& m= mSomeLongStackFIFOObject;
And then:
m.push_back(10);
It will shorten it and still let you use any variable you like.
If the variable is global, you can always do:
static inline void pushBack(int n) { mSomeLongStackFIFOObject.push_back(n); }
If you're trying to shorten the access, I can guess that you're using the variable more than once; then it could make sense to try to put all the accesses in a function that belongs to the class.
You can achieve the desired behaviour by binding the object mSomeLongStackFIFOObject to the member function push_back and using a placeholder for its argument. This requires at least a C++11 compiler.
Consider the following example:
#include <functional>
#include <iostream>
struct A {
void push_back(const int& n) { std::cout << "push_back(" << n << ")\n"; }
};
int main() {
A mSomeLongStackFIFOObject;
std::function<void(const int&)> pushToLastUsed = std::bind(
&A::push_back,
&mSomeLongStackFIFOObject,
std::placeholders::_1
);
pushToLastUsed(10); // push_back(10)
}
Some notes about this:
As Mirko already mentioned correctly, calling a non-static member function is basically the same as calling a static member function with this as implicit first parameter. The binding of an instance of struct A as first parameter makes use of this fact.
Type inference using auto does work for member functions without any parameters but not in the case above.
If the non-static member function is overloaded (e.g. std::vector<T>::push_back) you have to explicitly state the template parameters for the function template std::bind. See Using std::tr1::bind with std::vector::push_back
or Are there boost::bind issues with VS2010? for further information.
With newer C++ features, you often give a function as a parameter, for example:
// File A.cpp
void do_something(Foo* foo) { ... }
void A::process_foo(){
for_each( foo_list.begin(), foo_list.end(), do_something );
}
But where should I actually put the function do_something(...) when I work with classes? I can not make it a private member, since I would loose this when passing the parameter to for_each.
So I tend to just define a plain function do_something(...) in my implementation file A.cpp, like given in the code above. Since this is visible by the implementation of A only, I do not risk namespace pollution. Since a similiar function in other classes would also only be visible in their implementation, I also do not risk to have a name collision with a similiar function of another class.
Is this the right way?
Another idea would be to use a Lambda. I'm not very familiar with Lambdas, so I don't know whether I should use them as much as possible or only if absolutely necessary...
The third argument of std::for_each needs to be function or function object with one argument such as it may be called with an element of the range defined by first two arguments of for_each. Then you have following options (assuming that foo_list stores Foo*):
Use regular function
void do_someting(Foo*){...}
for_each(..., do_something);
You can put the function wherever it is suitable. If this is for local use, the anonymous namespace is the best option. But it may be e.g. defined in a separate compilation unit.
Use static method
static void do_something(Foo*){...}
for_each(..., &Foo::do_something);
Note that it does not need necessarily to be static method of Foo.
Use lambda
for_each(...,[](Foo* f){...});
Use a method of Foo class (even private) and std::bind
void method(){...}
for_each(..., std::bind(&Foo::method, _1));
There are other options but those are the most common.
C++11 solution
If you can use C++11, prefer range-based for instead of std::for_each and just write code in-place. Like this:
for (const auto& value : foo_list)
{
// do something with the value
}
It is less verbose and more convenient. It iterates through all of the elements one by one, just like std::for_each algorithm. And you can explicitly specify that you don't want to modify elements by putting const auto&, or simply auto (without reference).
Partial-C++11
If your compiler has no support of range-based fors, but has support of lambdas (like Visual Studio 2010), simply put function into lambda:
for_each( foo_list.begin(), foo_list.end(),
[] (const FooList::value_type& value) { /* do something with the value */; });
C++98
If you can use none of the above C++11 features, most of STL algorithms look pathetic. Whichever you place do_something function to, it will be decoupled from the calling code, which is very hard to read. Prefer simple iterator-based for in this case:
for (FooList::iterator pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue)
{
// do something with the pValue
}
PS I prefer the latter form even for "Partial-C++11" case, when you cannot use range-based fors, but can replace FooList::iterator with simple auto. It is very helpful when you would have to write something more complicated, like std::list<std::string>::const_iterator. I think the following is better than std::for_each with lambda:
for (auto pValue = foo_list.begin(); pValue != foo_list.end(); ++pValue)
{
// do something with the pValue
}
Let's say this is a C function to be wrapped:
void foo(int(__stdcall *callback)());
The two main pitfalls with C function pointer callbacks are:
Not being able to store bind expressions
Not being able to store capturing lambdas
I would like to know the best way to wrap functions like these to do so. The first is particularly useful for a member function callback, and the second for an inline definition that uses surrounding variables, but those are not the only uses.
The other property of these particular function pointers is that they need to use the __stdcall calling convention. This, to my knowledge, eliminates lambdas as an option completely, and is a bit of a nuisance otherwise. I'd like to allow at least __cdecl as well.
This is the best I am able to come up with without things starting to bend back to relying on support that function pointers don't have. It would typically be in a header. Here is the following example on Coliru.
#include <functional>
//C function in another header I have no control over
extern "C" void foo(int(__stdcall *callback)()) {
callback();
}
namespace detail {
std::function<int()> callback; //pretend extern and defined in cpp
//compatible with the API, but passes work to above variable
extern "C" int __stdcall proxyCallback() { //pretend defined in cpp
//possible additional processing
return callback();
}
}
template<typename F> //takes anything
void wrappedFoo(F f) {
detail::callback = f;
foo(detail::proxyCallback); //call C function with proxy
}
int main() {
wrappedFoo([&]() -> int {
return 5;
});
}
There is, however, a major flaw. This is not re-entrant. If the variable is reassigned to before it's used, the old function will never be called (not taking into account multithreading issues).
One thing I have tried that ended up doubling back on itself was storing the std::function as a data member and using objects, so each would operate on a different variable, but there was no way to pass the object to the proxy. Taking the object as a parameter would cause the signature to mismatch and binding it would not let the result be stored as a function pointer.
One idea I have, but have not played around with is a vector of std::function. However, I think the only real safe time to erase from it would be to clear it when nothing is using it. However, each entry is first added in wrappedFoo, then used in proxyCallback. I'm wondering if a counter that is incremented in the former and decremented in the latter, then checked for zero before clearing the vector would work, but it sounds like a more convoluted solution than necessary anyway.
Is there any way to wrap a C function with a function pointer callback such that the C++ wrapped version:
Allows any function object
Allows more than just the C callback's calling convention (if it's critical that it's the same, the user can pass in something with the right calling convention)
Is thread-safe/re-entrant
Note: The obvious solution, stated as part of Mikael Persson's answer, is to make use of the void * parameter that should exist. However, this is sadly not a be-all, end-all option, mostly due to incompetence. What possibilities exist for those functions that do not have this option is where this can get interesting, and is the primary route to a very useful answer.
You are, unfortunately, out of luck.
There are ways to generate code at runtime, for example you can read on LLVM trampoline intrinsics where you generate a forwarding function that stores additional state, very akin to lambdas but runtime defined.
Unfortunately none of those are standard, and thus you are stranded.
The simplest solution to pass state is... to actually pass state. Ah!
Well defined C callbacks will take two parameters:
A pointer to the callback function itself
A void*
The latter is unused by the code itself, and simply passed to the callback when it is called. Depending on the interface either the callback is responsible to destroy it, or the supplier, or even a 3rd "destroy" function could be passed.
With such an interface, you can effectively pass state in a thread-safe & re-entrant fashion at the C level, and thus naturally wrap this up in C++ with the same properties.
template <typename Result, typename... Args)
Result wrapper(void* state, Args... args) {
using FuncWrapper = std::function<Result(Args...)>;
FuncWrapper& w = *reinterpret_cast<FuncWrapper*>(state);
return w(args...);
}
template <typename Result, typename... Args)
auto make_wrapper(std::function<Result(Args...)>& func)
-> std::pair<Result (*)(Args...), void*>
{
void* state = reinterpret_cast<void*>(&func);
return std::make_pair(&wrapper<Result, Args...>, state);
}
If the C interface does not provide such facilities, you can hack around a bit, but ultimately you are very limited. As was said, a possible solution is to hold the state externally, using globals, and do your best to avoid contention.
A rough sketch is here:
// The FreeList, Store and Release functions are up to you,
// you can use locks, atomics, whatever...
template <size_t N, typename Result, typename... Args>
class Callbacks {
public:
using FunctionType = Result (*)(Args...);
using FuncWrapper = std::function<Result(Args...)>;
static std::pair<FunctionType, size_t> Generate(FuncWrapper&& func) {
// 1. Using the free-list, find the index in which to store "func"
size_t const index = Store(std::move(state));
// 2. Select the appropriate "Call" function and return it
assert(index < N);
return std::make_pair(Select<0, N-1>(index), index);
} // Generate
static void Release(size_t);
private:
static size_t FreeList[N];
static FuncWrapper State[N];
static size_t Store(FuncWrapper&& func);
template <size_t I, typename = typename std::enable_if<(I < N)>::type>
static Result Call(Args...&& args) {
return State[I](std::forward<Args>(args)...);
} // Call
template <size_t L, size_t H>
static FunctionType Select(size_t const index) {
static size_t const Middle = (L+H)/2;
if (L == H) { return Call<L>; }
return index <= Middle ? Select<L, Middle>(index)
: Select<Middle + 1, H>(index);
}
}; // class Callbacks
// Static initialization
template <size_t N, typename Result, typename... Args>
static size_t Callbacks<N, Result, Args...>::FreeList[N] = {};
template <size_t N, typename Result, typename... Args>
static Callbacks<N, Result, Args...>::FuncWrapper Callbacks<N, Result, Args...>::State[N] = {};
This problem has two challenges: one easy and one nearly impossible.
The first challenge is the static type transformation (mapping) from any callable "thing" to a simple function pointer. This problem is solved with a simple template, no big deal. This solves the calling convention problem (simply wrapping one kind of function with another). This is already solved by the std::function template (that's why it exists).
The main challenge is the encapsulation of a run-time state into a plain function pointer whose signature does not allow for a "user-data" void* pointer (as any half-decent C API would normally have). This problem is independent of language (C, C++03, C++11) and is nearly impossible to solve.
You have to understand a fundamental fact about any "native" language (and most others too). The code is fixed after compilation, and only the data changes at run-time. So, even a class member function that appears as if it's one function belonging to the object (run-time state), it's not, the code is fixed, only the identity of the object is changed (the this pointer).
Another fundamental fact is that all external states that a function can use must either be global or passed as a parameter. If you eliminate the latter, you only have global state to use. And by definition, if the function's operation depends on a global state, it cannot be re-entrant.
So, to be able to create a (sort-of-)re-entrant* function that is callable with just a plain function pointer and that encapsulate any general (state-ful) function object (bind'ed calls, lambdas, or whatever), you will need a unique piece of code (not data) for each call. In other words, you need to generate the code at run-time, and deliver a pointer to that code (the callback function-pointer) to the C function. That's where the "nearly impossible" comes from. This is not possible through any standard C++ mechanisms, I'm 100% sure of that, because if this was possible in C++, run-time reflection would also be possible (and it's not).
In theory, this could be easy. All you need is a piece of compiled "template" code (not template in the C++ sense) that you can copy, insert a pointer to your state (or function object) as a kind of hard-coded local variable, and then place that code into some dynamically allocated memory (with some reference counting or whatever to ensure it exists as long as it's needed). But making this happen is clearly very tricky and very much of a "hack". And to be honest, this is quite ahead of my skill level, so I wouldn't even be able to instruct you on how exactly you could go about doing this.
In practice, the realistic option is to not even try to do this. Your solution with the global (extern) variable that you use to pass the state (function object) is going in the right direction in terms of a compromise. You could have something like a pool of functions that each have their own global function object to call, and you keep track of which function is currently used as a callback, and allocate unused ones whenever needed. If you run out of that limited supply of functions, you'll have to throw an exception (or whatever error-reporting you prefer). This scheme would be essentially equivalent to the "in theory" solution above, but with a limited number of concurrent callbacks being used. There are other solutions in a similar vein, but that depends on the nature of the specific application.
I'm sorry that this answer is not giving you a great solution, but sometimes there just aren't any silver bullets.
Another option is to avoid using a C API that was designed by buffoons who never heard of the unavoidable and tremendously useful void* user_data parameter.
* "sort-of" re-entrant because it still refers to a "global" state, but it is re-entrant in the sense that different callbacks (that need different state) do not interfere with each other, as is your original problem.
As said before, a C function pointer does not contain any state, so a callback function called with no arguments can only access global state. Therefore, such a "stateless" callback function can be used only in one context, where the context is stored in a global variable. Then declare different callbacks for different contexts.
If the number of callbacks required changes dynamically (for example, in a GUI, where each windows opened by the user requires a new callback to handle input to that window), then pre-define a large pool of simple state-less callbacks, that map to a statefull callback. In C, that could be done as follows:
struct cbdata { void (*f)(void *); void *arg; } cb[10000];
void cb0000(void) { (*cb[0].f)(cb[0].arg); }
void cb0001(void) { (*cb[1].f)(cb[1].arg); }
...
void cb9999(void) { (*cb[9999].f)(cb[99999].arg); }
void (*cbfs[10000])(void) =
{ cb0000, cb0001, ... cb9999 };
Then use some higher level module to keep a list of available callbacks.
With GCC (but not with G++, so the following would need to be in a strictly C, not C++ file), you can create new callback functions even on the fly by using a not-so-well-known GCC feature, nested functions:
void makecallback(void *state, void (*cb)(void *), void (*cont)(void *, void (*)()))
{
void mycallback() { cb(state); }
cont(state, mycallback);
}
In this case, GCC creates the code for the necessary code generation for you. The downside is, that it limits you to the GNU compiler collection, and that the NX bit cannot be used on the stack anymore, as even your code will require new code on the stack.
makecallback() is called from the high-level code to create a new anonymous callback function with encapsulated state. If this new function is called, it will call the statefull callback function cb with arg state. The new anonymous callback function is useable, as long, as makecallback() does not return. Therefore, makecallback() returns control to the calling code by calling the passed in "cont" function. This example assumes, that the actual callback cb() and the normal continue function cont() both use the same state, "state". It is also possible to use two different void pointers to pass different state to both.
The "cont" function may only return (and SHOULD also return to avoid memory leaks), when the callback is no longer required. If your application is multi-threaded, and requires the various callbacks mostly for its various threads, then you should be able to have each thread at startup allocate its required callback(s) via makecallback().
However, if your app is multi-threaded anyways, and if you have (or can establish) a strict callback-to-thread relationship, then you could use thread-local vars to pass the required state. Of course, that will only work, if your lib calls the callback in the right thread.
I have a std::vector<T> of some type that's part of a class and that I need to iterate through in a lot of different places in my code, so I thought I'd be smart and create a function IterateAttributes, and pass it a boost::function object that I can in the loop and pass a single element and then I can pass any function to do work on the elements.
This seems a good idea until you have to implement it, then the problem comes of what does the passed in function return and does it need other arguments. It seems like I either have to find a way to do this more generically, like using templates, or I have to create overloads with function objects taking different args.
I think the first (more generic) options is probably better, however how would I go about that?
Below is a trial that doesn't work, however if I wanted to have a number of args, and all but the Attribute (a struct) arg mandatory. How should I go about it?
template <typename T> template <typename arg>
void ElementNode::IterateAttributes(boost::function<T (arg, Attribute)> func_)
{
std::vector<Attribute>::iterator it = v_attributes.begin();
for (; it != v_attributes.end(); it++)
{
func_(arg, *it);
}
}
Is that what you mean:
template <typename T, typename arg>
void ElementNode::IterateAttributes(boost::function<T (arg, Attribute)> func_, arg a)
{
std::vector<Attribute>::iterator it = v_attributes.begin();
for (; it != v_attributes.end(); it++)
{
func_(a, *it);
}
}
that allows only one parameter of any type - if you want you can introduce also version for more parameters.
About return value - what to do about it depends on what value it acctually is - the generic (and probably unnecesary) solution would be to return std::list<T>, but that would create more problems than it would solve i guess. If return type varies (not only in type but also in meaning) then I suggest modyfying templated function so it takes reference/pointer to overall result and updates it accordingly:
template <typename T> template <typename arg>
void ElementNode::IterateAttributes(boost::function<voidT (arg, Attribute, T&)> func_)
{
std::vector<Attribute>::iterator it = v_attributes.begin();
T result;
for (; it != v_attributes.end(); it++)
{
func_(arg, *it, result);
}
return result;
}
That's a quick workaround, it works but it's ugly, error prone, and pain to debug.
If you want variable parameter amount, then you would have to create several templates of above function - i just tested if it's possible:
template <typename T>
T boo(T){
}
template <typename T, typename TT>
TT boo(T,TT){
}
void test()
{
int i;
i= boo<int>(0);
i=boo<int,double>(0,0.0);
}
You must remember that functions passed to IterateAttributes must match exatly parameters given to Iterate function. That also means that you cannot use in it's prototype default values - probably you will have to define several overloaded versions like
void func_(Attribute,arg1, arg2,arg3){...}
void func_(Attribute A,arg1 a1,arg2 a2){func_(A,a1, a2,default3);}
void func_(Attribute A,arg1 a1){func_(A,a1, default2,default3);}
void func_(Attribute A){func_(A,default1, default2,default3);}
a) You want to iterate over the array and do something with each element there: in this case, you want functions that all take an array element and return void. Simple.
b) You want to partially apply functions with more arguments on each element: Write a custom functor around your function which stores the additional, pre-assigned arguments, or use boost::bind to effectively do the same.
Example:
vector<string> myStrings; // assign some values
// define a function with an additional argument
void myFunc(string message, string value)
{
cout << message << value << endl;
}
// allow partial application, i.e. "currying"
struct local_function
{
static string message;
static void myFunc_Curried(string value)
{
myFunc(message, value);
}
};
local_function::message = "the array contains: ";
// apply the curried function on all elements in the array
for_each(myStrings.begin(), myStrings.end(), local_function::myFunc_Curried);
The functor operates statically only for demonstration purposes. If message is bound to an instance of the struct, you will need something like boost::bind anyway to bind the instance pointer this in order to actually call the curried function. However, if the function I want to apply is used only locally, I prefer following the more readable static approach.
What you are trying to accomplish makes very good sense, and is also built directly into functional languages (for example F#). It is possible to achieve in C++, but requires some workarounds in the aforementioned case b. Please note if writing your own functor, as in my example, that it is common to place the arguments you want to curry away always at the beginning, and to "fill in" the arguments from the beginning to the end when partially applying.
Summarizing the comments and more thoughts:
Use bind to bind the other arguments, then use for_each on the resulting functor.
To handle return values, you need to think about what the return values mean. If you need to use the values in some way (say, perform a reduction, or use them to influence whether or not to continue performing the operation, etc), then you can use another functor to wrap the original to perform the thing you want.
You could do the same or more using BOOST_FOREACH or C++0x for each. That would even take less code to write.
In the Boost Signals library, they are overloading the () operator.
Is this a convention in C++? For callbacks, etc.?
I have seen this in code of a co-worker (who happens to be a big Boost fan). Of all the Boost goodness out there, this has only led to confusion for me.
Any insight as to the reason for this overload?
One of the primary goal when overloading operator() is to create a functor. A functor acts just like a function, but it has the advantages that it is stateful, meaning it can keep data reflecting its state between calls.
Here is a simple functor example :
struct Accumulator
{
int counter = 0;
int operator()(int i) { return counter += i; }
}
...
Accumulator acc;
cout << acc(10) << endl; //prints "10"
cout << acc(20) << endl; //prints "30"
Functors are heavily used with generic programming. Many STL algorithms are written in a very general way, so that you can plug-in your own function/functor into the algorithm. For example, the algorithm std::for_each allows you to apply an operation on each element of a range. It could be implemented something like that :
template <typename InputIterator, typename Functor>
void for_each(InputIterator first, InputIterator last, Functor f)
{
while (first != last) f(*first++);
}
You see that this algorithm is very generic since it is parametrized by a function. By using the operator(), this function lets you use either a functor or a function pointer. Here's an example showing both possibilities :
void print(int i) { std::cout << i << std::endl; }
...
std::vector<int> vec;
// Fill vec
// Using a functor
Accumulator acc;
std::for_each(vec.begin(), vec.end(), acc);
// acc.counter contains the sum of all elements of the vector
// Using a function pointer
std::for_each(vec.begin(), vec.end(), print); // prints all elements
Concerning your question about operator() overloading, well yes it is possible. You can perfectly write a functor that has several parentheses operator, as long as you respect the basic rules of method overloading (e.g. overloading only on the return type is not possible).
It allows a class to act like a function. I have used it in a logging class where the call should be a function but i wanted the extra benefit of the class.
so something like this:
logger.log("Log this message");
turns into this:
logger("Log this message");
Many have answered that it makes a functor, without telling one big reason why a functor is better than a plain old function.
The answer is that a functor can have state. Consider a summing function - it needs to keep a running total.
class Sum
{
public:
Sum() : m_total(0)
{
}
void operator()(int value)
{
m_total += value;
}
int m_total;
};
You may also look over the C++ faq's Matrix example. There are good uses for doing it but it of course depends on what you are trying to accomplish.
The use of operator() to form functors in C++ is related to functional programming paradigms that usually make use of a similar concept: closures.
A functor is not a function, so you cannot overload it.
Your co-worker is correct though that the overloading of operator() is used to create "functors" - objects that can be called like functions. In combination with templates expecting "function-like" arguments this can be quite powerful because the distinction between an object and a function becomes blurred.
As other posters have said: functors have an advantage over plain functions in that they can have state. This state can be used over a single iteration (for example to calculate the sum of all elements in a container) or over multiple iterations (for example to find all elements in multiple containers satisfying particular criteria).
Start using std::for_each, std::find_if, etc. more often in your code and you'll see why it's handy to have the ability to overload the () operator. It also allows functors and tasks to have a clear calling method that won't conflict with the names of other methods in the derived classes.
Functors are basically like function pointers. They are generally intended to be copyable (like function pointers) and invoked in the same way as function pointers. The main benefit is that when you have an algorithm that works with a templated functor, the function call to operator() can be inlined. However, function pointers are still valid functors.
One strength I can see, however this can be discussed, is that the signature of operator() looks and behaves the same across different types. If we had a class Reporter which had a member method report(..), and then another class Writer, which had a member method write(..), we would have to write adapters if we would like to use both classes as perhaps a template component of some other system. All it would care about is to pass on strings or what have you. Without the use of operator() overloading or writing special type adapters, you couldn't do stuff like
T t;
t.write("Hello world");
because T has a requirement that there is a member function called write which accepts anything implicitly castable to const char* (or rather const char[]). The Reporter class in this example doesn't have that, so having T (a template parameter) being Reporter would fail to compile.
However, as far I can see this would work with different types
T t;
t("Hello world");
though, it still explicitly requires that the type T has such an operator defined, so we still have a requirement on T. Personally, I don't think it's too wierd with functors as they are commonly used but I would rather see other mechanisms for this behavior. In languages like C# you could just pass in a delegate. I am not too familiar with member function pointers in C++ but I could imagine you could achieve the same behaviour there aswell.
Other than syntatic sugar behaviour I don't really see the strengths of operator overloading to perform such tasks.
I am sure there are more knowingly people who have better reasons than I have but I thought I'd lay out my opinion for the rest of you to share.
Another co-worker pointed out that it could be a way to disguise functor objects as functions. For example, this:
my_functor();
Is really:
my_functor.operator()();
So does that mean this:
my_functor(int n, float f){ ... };
Can be used to overload this as well?
my_functor.operator()(int n, float f){ ... };
Other posts have done a good job describing how operator() works and why it can be useful.
I've recently been using some code that makes very extensive use of operator(). A disadvantage of overloading this operator is that some IDEs become less effective tools as a result. In Visual Studio, you can usually right-click on a method call to go to the method definition and/or declaration. Unfortunately, VS isn't smart enough to index operator() calls. Especially in complex code with overridden operator() definitions all over the place, it can be very difficult to figure out what piece of code is executing where. In several cases, I found I had to run the code and trace through it to find what was actually running.
Overloading operator() can make the class object calling convention easier. Functor is one of the applications of operator() overloading.
It is easy to get confused between Functor and user-defined conversion function.
Below 2 examples show the difference between
1. Functor
2. User-defined conversion function
1. Functor:
struct A {
int t = 0;
int operator()(int i) { return t += i; } // must have return type or void
};
int main() {
A a;
cout << a(3); // 3
cout << a(4); // 7 (Not 4 bcos it maintaines state!!!)
}
2. User-defined conversion function:
struct A {
int t = 3;
operator int() { return t; } // user-defined conversion function
// Return type is NOT needed (incl. void)
};
int main() {
cout << A(); // 3 - converts the object{i:3} into integer 3
A a;
cout << a; // 3 - converts the object{i:3} into integer 3
}