Click here to Skip to main content
13,000,469 members (51,340 online)
Click here to Skip to main content
Add your own
alternative version


24 bookmarked
Posted 3 Mar 2003

A set of useful functors for creating and manipulating functors

, 3 Mar 2003
Rate this:
Please Sign up or sign in to vote.
Create functors from functions, member functions and manipulating functors.


Functors (function objects) play an important role in the Standard Template Library (STL). I have created several functors and supporting functions to manipulate functors such that new functors which are slightly modified from existing functors can easily be produced without rewriting the existing functors. This is in line with the principle of code reuse.


The following functors use partial specialization of template classes. Thus it cannot be compiled using Visual C++ since it does not support partial specialization. Anyone is welcome to port the code to Visual C++. You just need to change all the functors' name so that they will be unique, e.g. FunctionToFunctor1Arg, FunctionToFunctor2Arg, etc.

Conversion to functors

To manipulate functors, you must have functors in the first place. However a lot of useful code in legacy libraries are not functors. They are mostly functions. Some may be member functions. Even if there are functors, they may not be STL compliant (i.e. they do not typedef their return type and arguments). It is not always possible to convert these to STL compliant functors as the source code may not be available or it is very tedious to do manually.

To enable ease of converting these functions to STL compliant functors, four functors with partial specialization are created. In addition, an overloaded supporting function is provided to ease the usage of these four functors. The functors are: FunctionToFunctor, MemberFunctionToFunctor, ConstMemberFunctionToFunctor and FunctorToFunctor. The supporting function is to_functor. These functors are capable of converting functions, member functions or functors with up to ten arguments to the corresponding STL compliant functor. The number of arguments supporting is capped at ten because not a lot of functions have more than ten arguments.


The usage for FunctionToFunctor is FunctionToFunctor<Arg1T,Arg2T,....,ArgNT,RetT>, where Arg1T..ArgNT (N <=10) is the type for the various arguments of the function and RetT is the return type of the function. FunctionToFunctor's constructor requires the function's name.

The usage for MemberFunctionToFunctor is MemberFunctionToFunctor <ObjectT,Arg1T,Arg2T,....,ArgN,RetT>, where ObjectT is the type for the object containing the member function, Arg1T..ArgNT (N <=10) is the type for the various arguments of the function and RetT is the return type of the function. MemberFunctionToFunctor's constructor requires an instance of the object and the member function's name.

The usage for ConstMemberFunctionToFunctor is ConstMemberFunctionToFunctor <ObjectT,Arg1T,Arg2T,....,ArgN,RetT>, where ObjectT is the type for the object containing the member function, Arg1T..ArgNT (N <=10) is the type for the various arguments of the function and RetT is the return type of the function. ConstMemberFunctionToFunctor's constructor requires an instance of the object and the const member function's name.

The usage for FunctorToFunctor is FunctorToFunctor <FunctorT,Arg1T,Arg2T,....,ArgNT,RetT>, where FunctorT is the type for the functor, Arg1T..ArgNT (N <=10) is the type for the various arguments of the function and RetT is the return type of the function. FunctorToFunctor's constructor requires an instance of the functor.

The usage for to_functor is to_functor(function_name) for a function, to_functor(Object_instance, Object::function_name) for a member function and to_functor<Arg1T,Arg2T,...., ArgNT,RetT>(functor_instance) for a functor.


int Square(int x) {return x*x;}
FunctionToFunctor<int,int> square(Square);
cout << square(3) << endl;  // Output is 9

void Cube(const double& x, double& y) {y = x*x*x;}
FunctionToFunctor<const double&,double&,void> cube(Cube);
double z = 0.0;
cout << z << endl;  // Output is 8

struct Test
    bool IsPositive(double x) {return x > 0;}
    bool IsEven(int x) const {return !(x%2);}

MemberFunctionToFunctor<Test,double,bool> isPos(Test(), Test::IsPositive);
cout << isPos(3.2) << endl;  // Output is 1
ConstMemberFunctionToFunctor<Test,int,bool> isEven(Test(), Test::IsEven);
cout << isEven(4) << endl; // Output is 1

struct IsNegative
    bool operator()(int x) {return x < 0;}

FunctorToFunctor<IsNegative,int,bool> isNeg(IsNegative());
cout << isNeg(-2) << endl;  // Output is 1

cout << to_functor(Square)(2) << endl; // Output is 4
cout << to_functor(Test(), Test::IsPositive)(2.2) << endl; // Output is 1
cout << to_functor<int,bool>(IsNegative())(4) << endl;  // Output is 0

Alter results from a functor

Sometimes it is useful to be able to manipulate results from a functor. Let's say you want to create a functor which is similar to an existing functor except that its result is always 5 times larger. To accomplish this, AlterFunctorResult was created.


The usage for AlterFunctorResult is AlterFunctorResult<FunctorT,Arg1T,...ArgNT,RetT,BinaryOperationT> where FunctorT, ArgNT has the same definition as above and BinaryOperationT is a functor which performs binary operations, taking in two inputs and outputs a single output. Examples are the STL plus<>, minus<>, multiplies<> and divides<>. AlterFunctorResult's constructor requires an instance of the functor to be modified, the input to modify the output of the existing functor and an instance of the binary operation functor.


struct Cube  
  double operator()(double x) {return x*x;}  
AlterFunctorResult<Cube,double,double,multiplies<double> > 
cubeMultFive(Cube(), 5.0, multiplies<double>());  cout << 
cubeMultFive(3) << endl;  // Output is 135

Set arguments of functors with default values

The last set of functors perform the same operation as the functions bind1st and bind2nd of the STL library. That is, it allows an argument of a functor to have a default value. Thus when calling the functor, that argument can be left out. The limitation of the STL library is that it only supports functors with up to 2 arguments only. This set of functors is meant to complement the STL library by supporting functors with up to 10 arguments. By supporting up to 10 arguments, it also meant that the programmer can choose to bind from the first argument up to the tenth argument and not only the first two arguments.


The general format of the set of functors is BindFunctor??? where ??? is 1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th or 10th. All the ten set of functors have the same syntax. For example, to use BindFunctor3rd on a functor with 4 arguments, you will use BindFunctor3rd<FunctorT,Arg1T,Arg2T,Arg3T,Arg4T,RetT> and the constructor requires an instance of the functor and the default value for the 3rd argument.


struct BoxVolume
  int operator()(int length, int breadth, int height) 
     {return length * breadth * height;}
//Set breadth to be a constant 3
BindFunctor2nd<BoxVolume,int,int,int,int> boxvol(BoxVolume(), 3); 

cout << boxvol(2,5) << endl; // Output is 30
cout << boxvol(1,3) << endl; // Output is 9


The usefulness of these sets of functors depends on the imagination of the programmer. I believe it will be useful for generic programming as it will enable legacy C functions to be converted to functors which can then be manipulated in several ways before feeding into another function. This allows new functions to be created without recoding the existing functions.

Do let me know of any bugs in the code so that I may correct them. It is no joke trying to examine the code for minor coding errors as the codes are rather repetitive and boring to examine properly. I am also keen to learn of any desired improvement to the code.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Yap Chun Wei
Singapore Singapore
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralWow Awesome Pin
pyrokins6-Nov-05 14:20
memberpyrokins6-Nov-05 14:20 
GeneralThere are a set of such stuff in the existing STL Pin
Lai Shiaw San Kent9-Nov-03 20:46
memberLai Shiaw San Kent9-Nov-03 20:46 
GeneralRe: There are a set of such stuff in the existing STL Pin
Yap Chun Wei10-Nov-03 15:17
memberYap Chun Wei10-Nov-03 15:17 
Generalboost Pin
Goran Mitrovic5-Mar-03 12:21
sussGoran Mitrovic5-Mar-03 12:21 
GeneralRe: boost Pin
Yap Chun Wei5-Mar-03 15:01
memberYap Chun Wei5-Mar-03 15:01 
GeneralRe: boost Pin
Klaus Nowikow5-Mar-03 23:39
sussKlaus Nowikow5-Mar-03 23:39 
GeneralRe: boost Pin
Yap Chun Wei6-Mar-03 14:10
memberYap Chun Wei6-Mar-03 14:10 
GeneralRe: boost Pin
Craig Henderson11-Mar-03 21:43
memberCraig Henderson11-Mar-03 21:43 
GeneralRe: boost Pin
Yap Chun Wei12-Mar-03 16:13
memberYap Chun Wei12-Mar-03 16:13 
I stand by what I said. The libraries' use are limited. Just look at the compiler status for Windows: There is not even one compiler that doesn't fail on some test. GCC is the best among them.

I never discredit Boost nor doubt its usefulness but to sing its praises and saying everyone should use it and other code are of no good is what I don't like.

Your idea of portability is different from mine. Yes, Boost can work under different platforms but first you have to install the library! Sometimes, you just don't have the luxury of installing a library as and when you want to in a computer. During those times, it will be useful to just include a header file and the functionality is there. That is the KISS principle. You don't install a whole library just to use one feature. That is an overkill.

My code is not the best. It won't be and never will be. It will also never overtake what Boost can do. What I am trying to do here is presenting some functors which may be useful. Sure, I didn't do my homework beforehand so I actually duplicate some Boost features but there are other features which are not present in Boost also. I am not sure why some people is so crazy about Boost.

I would rather see comments about the article or the code. What are the bugs? How can I improve the code to make it more useful to others? Trying to debate the pros and cons of Boost is not what I wrote the article or the class for.Mad | :mad:
GeneralRe: boost Pin
FocusedWolf5-Jun-06 12:38
memberFocusedWolf5-Jun-06 12:38 
GeneralRe: boost Pin
FocusedWolf1-Dec-06 5:54
memberFocusedWolf1-Dec-06 5:54 
GeneralRe: boost Pin
Klaus Nowikow5-Mar-03 23:42
sussKlaus Nowikow5-Mar-03 23:42 
GeneralRe: boost Pin
WREY6-Mar-03 3:12
memberWREY6-Mar-03 3:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170624.1 | Last Updated 4 Mar 2003
Article Copyright 2003 by Yap Chun Wei
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid