What construct should be used as surrogate for std::function<> when C++11 is not available ?
The alternative should basically allow to access private member functions of one class from another class like in the example below (other features of std::function are not used). Class Foo is fixed and can not be changed much, I have only access to class Bar.
class Foo {
  friend class Bar; // added by me, rest of the class is fixed
  private:
  void doStuffFooA(int i);
  void doStuffFooB(int i);
};
class Bar {
  public:
  Bar( Foo foo, std::function< void (const Foo&, int) > func ) {
    myFoo = foo;
    myFooFunc = func;
  };
  private:
  doStuffBar( const &Foo foo ) {
    myFooFunc( foo, 3 );
  }
  Foo myFoo;
  std::function< void (const Foo&, int) > myFooFunc;
}
int main() {
  Foo foo(...);
  Bar barA( foo, &Foo::doStuffFooA );
  Bar barB( foo, &Foo::doStuffFooB );
  ...
}
Is there something similar to std::function before C++11?
Yes. There is Boost.Function (boost::function<>), which lately became part of the C++ Standard Library and provided a reference implementation for std::function<> ; similarly, Boost.Bind (boost::bind<>()) was adopted by the Standard and became std::bind<>().
It implements a technique called type erasure for holding callable objects of any type. Here is a possible, illustrative implementation of how such a class template could be defined from scratch (do not use in production code, this is just an example):
#include <memory>
template<typename T>
struct fxn { };
template<typename R, typename... Args>
struct fxn<R(Args...)>
{
public:
    template<typename F>
    fxn(F&& f) 
        : 
        _holder(new holder<typename std::decay<F>::type>(std::forward<F>(f)))
    { }
    R operator () (Args&&... args)
    { _holder->call(std::forward<Args>(args)...); }
private:
    struct holder_base
    { virtual R call(Args&&... args) = 0; };
    template<typename F>
    struct holder : holder_base
    {
        holder(F&& f) : _f(std::forward<F>(f)) { }
        R call(Args&&... args) { return _f(std::forward<Args>(args)...); }
        F _f;
    };
    std::unique_ptr<holder_base> _holder;
};
#include <iostream>
int main()
{
    fxn<void()> f = [] { std::cout << "hello"; };
    f();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With