QuickFunctor
About QuickFunctor
The QuickFunctor library consists of a collection of template classes and global functions to facilitate creation of and working with "functors", or "function objects", i.e. classes implementing an operator(). The functors in QuickFunctor are a substantial improvement (IMHO) over what the standard provides, with things like composition, expressions, "transform" operations, and even the naming convention.
Obviously, the work in the functor area didn't stop after the release of the last standard; there are related things in Boost, TR1, Loki and perhaps other places, but I think QuickFunctor is worth a look.
Note: to draw attention to some important things, an yellow background combined with a bold font will be used throught this page.


Content
Origin and acknowledgements
After trying several times to use the functors from the standard library and getting frustrated that it took too long to figure out how to do things, and that some things that I thought were reasonable to do just couldn't be done (or at least I was unable to find a way to do them), and after taking a quick look at other functor implementations, I started to develop QuickFunctor, with the declared purpose to create a library that allows its users to do pretty much anything that is reasonable to do with functors, and do it as easily and as efficiently as possible.
Many "idea leaders" in the C++ community (Bjarne Stroustrup, Scott Meyers, Herb Sutter, Daveed Vandevoorde, Nicolai Josuttis among them) advocate using functors, and I find their arguments persuasive. The standard library provides an implementation for functors, in the <functional> header, but from my point of view it has some drawbacks and limitations, which were significant enough to make me decide to write my own QuickFunctor, which I think has several advantages:
Highlights While the code of QuickFunctor is entirely new, it should be quite easy to notice that it is highly influenced by the interface of Alexander Stepanov's STL library and by Andrei Alexandrescu's "Modern C++ Design" book.
Why use QuickFunctor?
Here are some reasons to use functors from QuickFunctor:
Installation and testing
Download and unpack QuickFunctor and then modify the "additional include directories" in your IDE to add the directory include from wherever you unpacked QuickFunctor. Or move the directory somewhere else and specify that new place. The include directory is the only one you really need. The others are examples, documentation, ... Or, if you use a command line compiler, keep in mind to pass it the location of the include directory when you try to compile something.
To check that it works, you should be able to create an executable file from the source files in the main_tests directory (FunctorTst.cpp and main.cpp) and from other_tests (Functor.cpp, FunctorExpressionsTst.cpp and NumericCommonTypesTst.cpp). If you can't create the executable, there's no point in going further. You need to change or upgrade your compiler (well, or you can try to make changes in the library, to accommodate your compiler, but that's not going to be easy). That executable should produce an output similar to those in the directory results (keeping in mind that the order in which those tests are run is undetermined; so if you want to capture the output and do a comparison you might need to move things around in a text editor).
If you have Eclipse with CDT, you might try to import the included Eclipse project, in the root directory. I'm not sure if it's supposed to work, especially if you have a different version of Eclipse or CDT, but it may be worth giving it a try.
Developing code that uses QuickFunctor
First of all, you need to install it and you need a pretty new compiler. Old compilers are quite likely to be unable to deal with QuickFunctor. Here's what I currently know (as of 23 August 2007):
Please let me know if it works (or not) on your (different) system. Attaching the output of the test programs would be nice too. (See the e-mail address at the end of the file.)
Also, remember that everything is in the pearl namespace.
I would suggest this strategy for getting started with QuickFunctor:
An example using functors
Here's an example of what can be done with these functors. It's about a vector of cars and searching through it. I hope it's quite self-evident, but here are a few things worth noticing: This example is meant to be looked at, but it's probably a good idea to compile it too; you may want to check the installation section above. You'll have to download and unpack QuickFunctor, copy this example code to a .cpp file and compile that file, making sure that you pass to the compiler the include directory from where you unpacked QuickFunctor. With GCC it's the -I option. Various IDEs and compilers have their own ways of specifying where the "additional include directories" are. (The file main_tests/FunctorTst.cpp has a slightly modified version of this example.)
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

#include <FullFunctor.h>

using namespace std;
using namespace pearl;

struct Car
{
    string make;
    string model;
    int mpg;

    Car(const string& make, const string& model, int mpg) : make(make), model(model), mpg(mpg) {}
};

ostream& operator<<(ostream& out, const Car& car)
{
    out << car.make << " " << car.model << " " << car.mpg;
    return out;
}

// Finds the cars that satisfy some given condition and displays them.
// To do so it moves them to the beginning of the vector.
void findCars(vector<Car>& v, const Functor<bool (Car&)>& test)
{
    vector<Car>::iterator it;
    it = partition(v.begin(), v.end(), test);

    cout << "found " << it - v.begin() << " result(s):\n------------------\n";
    for (vector<Car>::iterator it1 = v.begin(); it1 != it; ++it1)
    {
        cout << (*it1) << endl;
    }
    cout << "**************************************\n";
}

bool hasTdi(const string& s)
{
    return string::npos != s.find_first_of("TDI");
}

void sampleUsage()
{
    vector<Car> v;
    cout << "=========================== sampleUsage() ========================================\n";
    v.push_back(Car("Toyota", "Corolla", 29));
    v.push_back(Car("VW", "Golf TDI", 41));
    v.push_back(Car("Toyota", "Land Cruiser", 14));
    v.push_back(Car("Toyota", "Avalon", 23));
    v.push_back(Car("Toyota", "Prius", 48));
    v.push_back(Car("VW", "Jetta", 32));
    v.push_back(Car("Honda", "Accord V6", 24));
    v.push_back(Car("Honda", "Accord V4", 27));

    cout << "Cars that have at least 23 mpg\n";
    findCars(v, mkF(&Car::mpg) >= 23);

    cout << "Cars that have the mpg between 23 and 41\n";
    findCars(v, mkF(&Car::mpg) >= 23 && mkF(&Car::mpg) <= 41);

    cout << "Toyotas that have at least 25 mpg\n";
    findCars(v, mkF(&Car::make) == "Toyota" && mkF(&Car::mpg) >= 25);

    vector<Car>::iterator it;
    it = find_if(v.begin(), v.end(), mkF(hasTdi).comp<1>(mkF(&Car::model)));
    //  mkF(hasTdi).o(mkF(&Car::model)) is a shortcut for the test above
    cout << "A car that has TDI: " << (*it) << endl;
}

int main()
{
    sampleUsage();
}


/*output:
=========================== sampleUsage() ========================================
Cars that have at least 23 mpg
found 7 result(s):
------------------
Toyota Corolla 29
VW Golf TDI 41
Honda Accord V4 27
Toyota Avalon 23
Toyota Prius 48
VW Jetta 32
Honda Accord V6 24
**************************************
Cars that have the mpg between 23 and 41
found 6 result(s):
------------------
Toyota Corolla 29
VW Golf TDI 41
Honda Accord V4 27
Toyota Avalon 23
Honda Accord V6 24
VW Jetta 32
**************************************
Toyotas that have at least 25 mpg
found 2 result(s):
------------------
Toyota Corolla 29
Toyota Prius 48
**************************************
A car that has TDI: VW Golf TDI 41
*/
Note. If you can't compile this example you should revisit the installation section, above.
I would like to suggest an exercise: try to redo this example with the standard library or with your favorite functor library, just to see what it takes and how easy is it to do it. You'll probably want to add "getter" methods for the data members, to be able to create any functors out of them. But even if you add the "getters", you might have trouble using and combining them. Also, note that most of the code above deals with preparing the vector and displaying the results. There are just a few lines that have anything to do with functors.
You can find my own attempt at a Boost porting below. Please don't hesitate to write me if you have a better approach. I'm not really knowledgeable about Boost, so there might be simpler ways to do what I did.
Reference
A detailed description of QuickFunctor, fully supported by examples.
Types of functors
Functors are objects of various classes. Any functor has exactly one signature, which is a function signature enclosed in brackets <R (P1, P2, ... , Pn)>. Having that signature means that it has a member function R operator()(P1, P2, ... , Pn) const, so it takes arguments of types P1, P2, ... Pn and returns R. The maximum number of parameters is determined when generating the file Functor.h (see Other notes, below); by default it's 3, and so "n" can take any value between 0 and 3. When n is 0, it means that there are no parameters: the signature <R ()> corresponds to a member function R operator()() const, taking no parameters.
A way to classify them would be into "unnamed functors" and "named functors". There are many different functor classes, which, BTW, are template classes, whose template parameters are often other functor classes, so they are usually pretty complex; but the end user doesn't need to know about them, because they should never be used directly. While this complexity doesn't prevent them from being passed to standard algorithms, there are two issues with them: on the one hand it is very cumbersome to have a variable or a parameter with such a type, and on the other hand it doesn't allow genericity. To address these issues, "named functors" have been introduced. They have a simple type, matching their signature. The type Functor<R (P1, P2, ... , Pn)> is a functor with the signature <R (P1, P2, ... , Pn)>. The type Functor<R (P1, P2, ... , Pn)> can easily be used for variables or parameters. The "unnamed" functors are all the others, created by mkF or by expressions or operations on existing functors. Apart from the fact that the template arguments of the named functors consist of their signature, while the template arguments of the unnamed functors are usually complex and hard to deal with directly, both named and unnamed functors behave the same and support the same operations.
The functors from QuickFunctor are immutable. Once they are created, they don't change. The only thing you can do to a functor variable is to assign it a new value. Apart from operator=(), they only have const methods. Named functors can be assigned any functor (named or unnamed) that has the same signature.
A named functor just containes a wrapper object, which contains a pointer to another (usually unnamed) functor, which has the actual implementation. Initially that wrapper used a class called SharedPtr to handle its pointer. Basically, that shared the same pointer among several named functors. Starting with version 0.8.1.0, this is the default, but you can also use other kinds of "smart pointers". The other one provided is ClonedPtr, which does a "deep clone" of the object pointed to on construction or assignment. You can also write your own. It has to support a simple interface, described at the beggining of the file SmartPointers.h. Another one that would be useful but is not provided is a "synchronized SharedPtr". SharedPtr's functions are "non-synchronized", so if you call them from different threads for objects that share a pointer you may leave an object of the class RefCntHolder (which is an internal class of SharedPtr) in an inconsistent state, when those threads are simultaneously manipulating references to the same underlying pointer. A "synchronized SharedPtr" is not provided because it can't be done portably with the standard library only. You can write your own, though, and, upon request, I'll provide information about how to do this if what I said here is not enough.
There is a price to pay for the convenience of named functors: they need more memory, they need heap memory, and invoking them causes a virtual function call. The unnamed functors only use the stack (unless allocated with new) and have no virtual functions. Usually this is of little importance, but sometimes it can noticeably slow down a call (if it's in the innermost loop): on the one hand the virtual call itself usually takes longer, and on the other hand the compiler will be more limited in the optimizations it can perform.
In the examples that follow, named functors will be used a lot. That is done mainly to show what are the signatures of the functors involved, but it could have been avoided and it's generally not a good practice to follow in real-world usage of QuickFunctor.
Creating functors
Creating functors is not done by calling a constructor, but by calling mkF and its variants, or by calling functor operations on existing functors, or by using expressions.
Firstly, there's mkF. This will create a functor from (almost) any function, variable, constant or numeric or string literal. (There are some exceptions when dealing with classes that don't have a copy constructor.)
Sometimes we'd like to create a functor with a different signature than what mkF would create; perhaps one that takes as its first parameter a pointer to an object, rather than a reference. Or one that returns a const string& rather than a string. Sometimes these can be done by using composition, casting or other operations, but it's usually more convenient to use one of the "modifiers" (or "suffixes") of mkF.
For functors created from data only (i.e. not from functions) there are mkFC, mkFR and mkFCR. While mkF creates a functor that returns some value type V, these variants return const V, V& and const V&, respectively.
For functors created by mkF from members (data or functions) of a class C, the first parameter of the functor is generally &C, except for const member functions, for which it is const C&. If that parameter should rather be a pointer (C* or const C*), the easiest way to do it is to add an "A" suffix to mkFXX: mkFA, mkFCA, mkFRA and mkFCRA. These will probably be most useful in code that deals with containers of (smart) pointers to classes. (Note that these are "convenience" functions; the same result could be obtained by using operations or composition on the "reference" functions: mkFA(f) <=> mkF(f).addr<1>() <=> mkF(f).comp<1>(mkF(addr<C>)) ).
When using named functor types, you may specify a "pointer use policy", to describe how the named functors should handle internally pointers to other functors. By default, SharedPtr is used, which shares an existing pointer when a named functor with the same type (including both signature and "pointer use policy") is used as a parameter to the copy constructor of a new named functor or to the operator=() of an existing named functor. This is the default, and so Functor<int (int), SharedPtr> is equivalent to just Functor<int (int)>. The alternative is ClonedPtr, which is recommended to be used when passing named functors among threads, to avoid issues that may result from the fact that SharedPtr's implementation is not synchronized. ClonedPtr should also probably be used when writing your own, mutable functors, derived from FBase.
Here's how the copy constructor and operator=() work for named functors. They can have a parameter that must be a functor with the same signature. If that functor is also a named functor with the same "pointer use policy", that policy will be taken into consideration and used appropriately. Otherwise, the parameter will be considered "generic" and a new wrapper will be created to hold a pointer to a copy of this parameter. Therefore it's advisable to avoid mixing ClonedPtr and SharedPtr, because it may lead to unexpected results when calls are made from different threads.
There are some predefined helper functions, which may be useful in some cases, by creating functors from them, with mkF. They can be used in compositions with existing functors or to simply pass them as arguments to standard algorithms (see the examples with mkF(identity<int>) in functorTstAlgorithms(), below, which prints a vector of int). These functions are located in <TemplMiscUtils.h>: There are also the null functors, which allow creating functors with a given signature but which don't do anything.
double f01(int x, char* p, double y) { return x + *p + y; }


struct TstStruct01
{
    int m() { return 7; }
    int cm() const { return 3; }

    const int cn;
    int n;
};


void functorTstCreation()
{
    cout << "======================= functorTstCreation() ===================================\n";
    // creating a functor from a global function
    Functor<double (int, char*, double)> fct1 (mkF(f01));

    // creating a functor from a value
    Functor<int ()> fct2 (mkF(5)); // constant 5
    Functor<long ()> fct2a (mkF(5L));
    cout << fct2() << " " << fct2a() << endl; // 5 5

    // creating a functor from a variable, showing that changing the variable changes the value of the functor
    int n (9);
    Functor<int ()> fct3 (mkF(n));
    cout << fct3() << endl; // 9
    n = 4; // changing the variable changes the value of the functor
    cout << fct3() << endl; // 4

    // creating a functor from a variable, showing all the combinations of const and reference
    string s ("abc");
    Functor<string ()> fct4 (mkF(s)); // return by value
    Functor<const string ()> fct4a (mkFC(s)); // return by const value
    Functor<string& ()> fct4b (mkFR(s)); // return by reference
    Functor<const string& ()> fct4c (mkFCR(s)); // return by const reference


    //----------------------------------------------------------------------------------

    // creating a functor from a method, taking a reference as the first param
    Functor<int (TstStruct01&)> fct5 (mkF(&TstStruct01::m)); // non-const method
    Functor<int (const TstStruct01&)> fct5a (mkF(&TstStruct01::cm)); // const method

    // creating a functor from a non-const data member
    Functor<int (TstStruct01&)> fct6 (mkF(&TstStruct01::n)); // non-const data member, return by value
    Functor<const int (const TstStruct01&)> fct6a (mkFC(&TstStruct01::n)); // non-const data member, return by const value
    Functor<int& (TstStruct01&)> fct6b (mkFR(&TstStruct01::n)); // non-const data member, return by reference
    Functor<const int& (const TstStruct01&)> fct6c (mkFCR(&TstStruct01::n)); // non-const data member, return by const reference

    // creating a functor from a const data member; like for the non-const, but the results are always const
    Functor<const int (TstStruct01&)> fct7 (mkF(&TstStruct01::cn)); // non-const data member, return by value
    Functor<const int (const TstStruct01&)> fct7a (mkFC(&TstStruct01::cn)); // non-const data member, return by const value
    Functor<const int& (TstStruct01&)> fct7b (mkFR(&TstStruct01::cn)); // non-const data member, return by reference
    Functor<const int& (const TstStruct01&)> fct7c (mkFCR(&TstStruct01::cn)); // non-const data member, return by const reference


    //----------------------------------------------------------------------------------

    // creating a functor from a method, taking a pointer as the first param
    Functor<int (TstStruct01*)> fct8 (mkFA(&TstStruct01::m)); // non-const method
    Functor<int (const TstStruct01*)> fct8a (mkFA(&TstStruct01::cm)); // const method

    // creating a functor from a non-const data member, taking a pointer
    Functor<int (TstStruct01*)> fct9 (mkFA(&TstStruct01::n)); // non-const data member, return by value
    Functor<const int (const TstStruct01*)> fct9a (mkFCA(&TstStruct01::n)); // non-const data member, return by const value
    Functor<int& (TstStruct01*)> fct9b (mkFRA(&TstStruct01::n)); // non-const data member, return by reference
    Functor<const int& (const TstStruct01*)> fct9c (mkFCRA(&TstStruct01::n)); // non-const data member, return by const reference

    // creating a functor from a const data member, taking a pointer
    Functor<const int (TstStruct01*)> fct10 (mkFA(&TstStruct01::cn)); // non-const data member, return by value
    Functor<const int (const TstStruct01*)> fct10a (mkFCA(&TstStruct01::cn)); // non-const data member, return by const value
    Functor<const int& (TstStruct01*)> fct10b (mkFRA(&TstStruct01::cn)); // non-const data member, return by reference
    Functor<const int& (const TstStruct01*)> fct10c (mkFCRA(&TstStruct01::cn)); // non-const data member, return by const reference


    //----------------------------------------------------------------------------------

    // creating a functor from helper functions
    Functor<const int (int)> fct11 (mkF(identity<const int>)); // !!! not "Functor<const int, const int>":
                                                // remember that "void f(const int);" is equivalent to "void f(int);"
    cout << fct11(15) << endl; // 15
    Functor<int& (int*)> fct12 (mkF(deref<int>));
    Functor<int (int*)> fct13 (mkF(derefV<int>));
    Functor<int* (int&)> fct14 (mkF(addr<int>));

    Functor<void ()> fct15 (mkF(nullFunctor0<void>));
    Functor<int (int)> fct16 (mkF(nullFunctor1<int, int>));

    //----------------------------------------------------------------------------------

    // creating named functors with specified sharing policy
    Functor<const int (int), SharedPtr> fct17 (mkF(identity<const int>)); // SharedPtr is the default anyway
    Functor<int (TstStruct01*), ClonedPtr> fct18 (mkFA(&TstStruct01::m));
    Functor<const string (), ClonedPtr> fct19 (mkFC(s)); 
    Functor<long (), ClonedPtr> fct20 (mkF(5L));
}
Operations
You can create another functor from an existing one by using "operations". One interesting thing about functor objects is that they are immutable; they don't change after they are created. The only thing you can do to a functor variable is to asssign it a new value; all the methods are const.
So there are many "operations" that look like they modify a functor, but what they are doing is creating and returning a new one.
The supported operations are:
Most operations create functors with the same number of arguments as the original, but these are the exceptions:
int f11(int x, char* p, int y) { return x + *p + y; }
char* f12(char& c) { return &c; }
int f13() { return 9; }

void functorTstOperations()
{
    cout << "======================= functorTstOperations() ===================================\n";
    char c (10);

    // a simple functor that returns "int" and takes 3 params (int, char*, int), representing the global function f11
    Functor<int (int, char*, int)> fct1 (mkF(f11));
    cout << fct1(4, &c, 7) << endl; // 4+10+7=21

    // fct2 is built by "composition on position 2", which effectively changes the type of the
    //    second argument from "char*" to "char&"
    // fct2(x, y, z) <=> fct1(x, f12(y), z) <=> fct1(x, &y, z)
    Functor<int (int, char&, int)> fct2 (fct1.comp<2>(mkF(f12)));
    cout << fct2(4, c, 7) << endl; // 4+10+7=21

    // by "composition on position 3" with mkF(f13), the third argument is effectively eliminated
    // fct2a(x, y) <=> fct1(x, y, f13())
    Functor<int (int, char*)> fct2a (fct1.comp<3>(mkF(f13)));
    cout << fct2a(4, &c) << endl; // 4+10+9=23

    // fct3 is built by "dereferencing the argument on position 2", so it behaves identically to fct2
    // fct3(x, y, z) <=> fct1(x, &y, z) <=> fct2(x, y, z)
    Functor<int (int, char&, int)> fct3 (fct1.deref<2>());
    cout << fct3(4, c, 7) << endl; // 4+10+7=21

    // by "dereferencing" the result of the functor created by mkF(f12),
    //    we really get the identity functor, returning what was passed to it
    // since fct4(c) returns a "char&", its result can be passed as the second argument to fct3
    Functor<char& (char&)> fct4 (mkF(f12).deref());
    cout << fct3(4, fct4(c), 7) << endl; // 4+10+7=21

    // by "taking the address of the argument on position 1" of fct4, that parameter becomes a pointer in fct5
    Functor<char& (char*)> fct5 (fct4.addr<1>());

    // by "taking the address of the result" of fct4, the result becomes a pointer in fct6
    Functor<char* (char&)> fct6 (fct4.addr());

    // by "binding on position 3", the third argument is eliminated and the result is the same as fct2a
    // fct7(x, y) <=> fct1(x, y, 9) <=> fct2a(x, y)
    Functor<int (int, char*)> fct7 (fct1.bind<3>(9));
    cout << fct7(4, &c) << endl; // 4+10+9=23

    // by "replacing the argument on position 3 with the one in position 1", the third argument is eliminated
    // fct8(x, y) <=> fct1(x, y, x)
    Functor<int (int, char*)> fct8 (fct1.del<3, 1>());
    cout << fct8(4, &c) << endl; // 4+10+4=18

    // by "applying the permutation <2, 3, 1>", the order of the arguments is changed
    // fct9(x, y, z) <=> fct1(y, z, x)
    Functor<int (char*, int, int)> fct9 (fct1.perm<2, 3, 1>());
    cout << fct9(&c, 4, 7) << endl; // 10+4+7=21

    // by "applying casting", static_cast is called for all arguments and for the result
    // fct10 is like fct1, with "int" cast to "char", so it overflows if passed arguments that are too big
    Functor<char (char, char*, char)> fct10 (fct1.cast<char, char, char*, char>());
    cout << (int)fct10(4, &c, 7) << endl; // 4+10+7=21
    cout << fct1(127, &c, 127) << endl; // 127+10+127=264;
    cout << (int)fct10(127, &c, 127) << endl; // 127+10+127=264; overflow (on most systems), so probably 8

}
Expressions (arithmetic, boolean, string)
As long as two functors return compatible types and take compatible arguments, it is possible to build expressions with them, using the following operators: "+(binary)", "-(binary)", "*(binary)", "/", "%", "<", ">", ">=", "<=", "==", "!=", "&&", "||", "&(binary)", "|", "^", "<<", ">>", "~", "!", "-(unary)", "+(unary)".
If both f1 and f2 have the signature <int (int)>, then f1 + f2 is a functor, which has the signature <int (int)> too and (f1 + f2)(a) returns f1(a) + f2(a), while f1 <= f2 has the signature <bool (int)> and (f1 <= f2)(a) returns f1(a) <= f2(a).
What happens if the functors involved in the expression are not of identical signatures? In a few words, the "expression functor" will be compilable and usable if it makes sense, and QuickFunctor tries really hard to do the "right thing". Roughly speaking, its result and parameters will be chosen in such a way as to avoid data loss by truncation. Another thing that is done is choosing the most derived class when the parameters on the same position are classes (or references or pointers to classes). For more details you can see the comments in CommonType.h and those in ApplyOp.h, but that's a difficult read; better look at the examples and do some experimentation.
I took the decision to allow expressions between functors with different number of parameters. For example, by adding a functor f1 with the signature <int (int)> to a functor f2 with the signature <int (int, int, int)>, the result is going to have the signature <int (int, int, int)>. The way the addition works is this: assuming that the parameters are called x, y and z, the result of (f1+f2)(x, y, z) will be f1(x) + f2(x, y, z). It's not completely right to allow this. However in some cases this makes a lot of sense, like when adding (or subtracting, comparing, ...) a functor with the signature <int (int)> to a literal constant or to a functor with the signature <int ()>. So this is allowed, until I'm presented with reasons good enough to forbid it. To determine the type of the parameters of the "expression functor", CommonParamType (from CommonType.h) is called as long as both functors have parameters in some position, and the types for the rest of the parameters are just copied from the remaining types of the functor with more parameters.
Another rather unusual thing is the ability to "add" functors that return void. Given two functors f1 and f2, if at least one of them returns void and their arguments are compatible, they can be "added", with the + operator. All this does is calling first the first functor, with whatever parameters it needs, and then calling the second functor; any results are ignored. The f1+f2 functor will return void. Being able to have additions (-, * or other operations are not allowed) with functors that return void is something experimental, which I feel might lead to something interesting but I don't currently have a very good reason for allowing it. There's assymetry there, because something can be added but not removed.
There's a special treatment for the << and >> operators. They are done in such a way that they work for both numbers and streams. See fct7 and fct7a in functorTstArithmExpr() for how would they work with streams, where it's possible to incorporate std::cout in a functor and print something at every call, without ostream being even in the signature of fct7a. Note that the functor for cout is created with mkFR, because we want to create a reference, not a copy.
Note that the header <FunctorExpressions.h> is needed for expressions, most likely along with <NumericCommonTypes.h> and/or <StringCommonTypes.h>.
int f21(int x) { return x + 10; }
int f22(short x) { return x * 3; }
int f23(int x, int y) { return x/y; }
string f24(const string& x) { return x + "#" + x; }
const string& f25(const string& x) { static string s; s = ">>" + x + "<<"; return s; } // not a good idea to have a "static", but it's just an example


void functorTstArithmExpr()
{
    cout << "======================= functorTstArithmExpr() ===================================\n";

    Functor<int (int)> fct1 (mkF(f21));
    Functor<int (short)> fct2 (mkF(f22));
    Functor<int (short)> fct3 (fct1 - fct2); // fct3(x) = (x + 10) - (x * 3)
    cout << fct3(4) << endl; // (4+10)-(4*3)=2

    Functor<int (short)> fct4 (mkF(f21) - mkF(f22)); // fct4(x) <=> fct(x)
    Functor<int (short)> fct5 (mkF(f21) - 2*mkF(f22) + 15); // fct4(x) = (x + 10) - 2*(x * 3) + 15
    cout << fct5(4) << endl; // (4+10)-2*(4*3)+15=5

    Functor<int (int, int)> fct6 (mkF(f21) - mkF(f23)); // fct6(x, y) = (x + 10) - (x / y)
    cout << fct6(8, 2) << endl; // (8+10)-(8/2)=14

    (mkFR(cout) << fct6 << "\n")(8, 2); // 14, as before, but the action of evaluatingthe whole functor does both the calculation and the printing
    Functor<ostream& (int, int)> fct7 (mkFR(cout) << fct6 << "\n"); // the corresponding named functor
    fct7(15, 3); // (15+10)-(15/3)=20 ; evaluating this also does the printing
    Functor<void (int, int)> fct7a (fct7.cast<void, int, int>());
    fct7a(15, 3); // (15+10)-(15/3)=20 ; evaluating this does the printing, like with fct7, but the signature has no reference to a stream

    cout << "---------- strings ---------" << endl;
    Functor<string (const string&)> fct8 (mkF(f24) + " added expr ptr");
    cout << fct8("WW") << endl; // "WW#WW added expr ptr"
    Functor<bool (string)> fct9 (mkF(identity<string>) == "str1");
    string a1 ("str1");
    cout << fct9(a1) << fct9("str1") << fct9("str2") << endl; // 110, meaning "true, true, false"

    Functor<string (const string&)> fct10 (mkF(f24) + " *** " + mkF(f25)); // note that the result is "string", even if f25 returns "const string&"
    cout << fct10("o") << endl; // "o#o *** >>o<<"
}


//----------------------- parameters of various members belong to derived classes ------------------

struct Base01
{
    int m1() { return 4; }
};

struct Der01 : public Base01
{
    Der01(int x1) : x(x1) {}
    Der01(int* p) : x(*p + 10) {}
    int x;
    int m2() const { return x; }
};

int f26(Base01* pb) { return pb->m1(); }
int f27(const Der01* pd) { return pd->m2(); }
int f28(int* p) { return *p; }
int f29(const Der01& d) { return d.m2() + 3; }

void functorTstArithmExprDer()
{
    cout << "====================== functorTstArithmExprDer() =================================\n";

    Functor<int (Der01*)> fct01 (mkF(f26) + mkF(f27) + mkFA(&Base01::m1)); // 4 + x->x + 4
    Der01 d (3);
    cout << fct01(&d) << endl; // 11

    Functor<int (int*)> fct02 (mkF(f28) * mkF(f29)); // *x * ((*x + 10) + 3)

    int x (2);
    int* p;
    CommonParamType<int*, const Der01&>::Type q (&x); // q is a "int*"
    p = q; // &x
    cout << fct02(p) << endl; // 30
}


//---------------------------- expressions with functors that return void --------------------------

void f210() { cout << "<inside f210>"; }
void f211() { cout << "<inside f211>"; }
int f212() { cout << "<inside f212>"; return 8; }
int f213(int x) { cout << "<inside f213; param: " << x << ">"; return 8; }

void functorTstVoidExpr()
{
    cout << "========================= functorTstVoidExpr() ===================================\n";

    Functor<void ()> fct1 (mkF(f210));
    Functor<void ()> fct2 (mkF(f211));
    Functor<int ()>  fct3 (mkF(f212));
    Functor<void ()> fct4 (fct1 + fct2);
    fct4(); cout << endl; // <inside f210><inside f211>
    fct4 += fct1;
    fct4(); cout << endl; // <inside f210><inside f211><inside f210>
    fct4 = fct1 + fct2 + fct3;
    fct4(); cout << endl; // <inside f210><inside f211><inside f212>
    fct4 += fct3;
    fct4(); cout << endl; // <inside f210><inside f211><inside f212><inside f212>
    Functor<void (int)> fct5 (fct4 + mkF(f213));
    fct5(20); cout << endl; // <inside f210><inside f211><inside f212><inside f212><inside f213; param: 20>
}
Usage with algorithms
Basically you can use them wherever a standard algorithm (like for_each, find_if, partition, ... ) takes a functor. They even have defined result_type, argument_type, first_argument_type and second_argument_type. A thing to notice is that if you have containers of (smart) pointers, you'll probably want to use the variants of mkF with the "A" suffix (see Creating functors, above), so the functors it creates take pointers too.
int f31(int x) { return x - 1000; }

struct Pers
{
    int m_id;
    string m_name;
    const string& getNameCst() const { return m_name; }
    const string& getName() { return m_name; }
    Pers(int id, string name) : m_id(id), m_name(name) {}
};


void functorTstAlgorithms()
{
    cout << "======================= functorTstAlgorithms() ===================================\n";

    cout << "------------------------------------------------------------------------------\n";
    cout << "### print vector<int>\n";
    vector<int> v1;
    v1.push_back(1000); v1.push_back(1002); v1.push_back(1005);
    for_each(v1.begin(), v1.end(), mkFR(cout) << " ## " << mkF(identity<int>)); //  ## 1000 ## 1002 ## 1005
    cout << endl;

    cout << "### print bitwise negation of vector<int>\n";
    for_each(v1.begin(), v1.end(), mkFR(cout) << " " << ~(mkF(identity<int>))); // bitwise negation:  -1001 -1003 -1006
    cout << endl;

    cout << "### print arithmetic negation of vector<int>\n";
    for_each(v1.begin(), v1.end(), mkFR(cout) << " " << -(mkF(identity<int>))); // arithmetic negation:  -1000 -1002 -1005
    cout << endl;

    cout << "### find x such that \"f31(x) > 1\"\n";
    vector<int>::iterator it0 (find_if(v1.begin(), v1.end(), mkF(f31) > 1));
    cout << *it0 << endl; // 1002

    cout << "### custom print of vector<Pers>\n";
    vector<Pers> v2;
    v2.push_back(Pers(10, "name p10")); v2.push_back(Pers(11, "name p11")); v2.push_back(Pers(100, "name p100"));
    for_each(v2.begin(), v2.end(), mkFR(cout) << " - " << mkF(&Pers::m_id) << " [" << mkF(&Pers::getName) << "]\n");

    cout << "### find first pers with id > 10 in vector<Pers>\n";
    vector<Pers>::iterator it21 (find_if(v2.begin(), v2.end(), mkF(&Pers::m_id) > 10));
    cout << it21->m_id << " " << it21->m_name << endl;

    cout << "### find first Pers whose bitwise negation is smaller than -20 in vector<Pers>\n";
    vector<Pers>::iterator it22 (find_if(v2.begin(), v2.end(), ~mkF(&Pers::m_id) < -20));