tags:

views:

403

answers:

3

One of the things that seems to be necessary with use of STL is a way to specify local functions. Many of the functions that I would normally provide cannot be created using STL function object creation tools ( eg bind ), I have to hand roll my function object.

Since the C++ standard forbids local types to be used as arguments in template instantiations the best I was able to use was to create a small library, ( just showing relevant parts )

// library header
class MyFunctionBase<R,T>  
{  
 public:  
   virtual ~MyFunctionBase();  
   virtual R operator()(const T &) const=0;  
};    


class  MyFunction<R,T> 
{   
    MyFunctionBase<R,T> *b; 
 public: 
    ~MyFunction()
    {
       delete b;
    }
    virtual R operator()(const T &) const
    {
        return (*b)(T);
    } 
};


// source file
....

    class func: public MyFunctionBase  ...
    std::stl_alg(....    MyFunction(new funct));

This has always seemed unwieldly to me. I guess to the people on the ISO committee believe so too and added a lambda to C++.

In the meantime how have compilers addressed this problem? ( Especially Windows compilers. )

A correction which might clarify a bit. Changelog: Nov 2 replaced to clarify Since the C++ standard forbids local classes as function objects

+4  A: 

The standard way is a "functor" - basically, a struct that supplies an operator()

For example:

struct MyMinFunctor {
  bool operator()(const int& a, const int& b) { return a > b; }
};

vector<int> v;
sort(v.begin(), v.end(), MyMinFunctor());

Because it is a struct/class, you can subclass any of the things like 'binary_operator' as well as maintain state for more advanced functors.

hazzen
+1  A: 

With C++0x you can use lambda's (as you mentioned):

for_each(container.begin(), container.end(),
  [](auto item) {
    // do something with item
  }
  );

This is already available in MS Visual C++ 2010 (currently in Community Tech Preview) and GCC 4.3.x (with the -std=c++0x compiler flag). However, without lambda's, you just need to provide a type that:

  1. Is default constructible
  2. Is copy constructible
  3. Defines a function operator overload

There are some algorithms that require binary function objects while there are some that require unary function objects. Refer your vendor's STL documentation to find out exactly which algorithms require binary function objects and which ones require unary function objects.

One thing you might also want to look into are the newer implementations of bind and function in TR1 (based on Boost.Bind and Boost.Function).

Dean Michael
+1  A: 

Boost.Bind, Boost.Function, and Boost.Lambda are your friends.