在C++11之前是否有类似于std::function的东西?

7
当C++11不可用时,应该使用什么构造作为std::function<>的代理?替代方案基本上应允许从另一个类中访问一个类的私有成员函数,就像下面的示例一样(没有使用std::function的其他功能)。类Foo已经固定,不能太多地进行更改,我只能访问类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 );
  ...
}

1
即使修复了明显的语法错误,这段代码也不应该编译。这两个 Bar 对象是使用指向私有成员函数的指针构造的,但是发生这种情况的代码没有访问这些成员的权限。这与 std::function 无关;它不能打破访问规则。 - Pete Becker
1个回答

10
在C++11之前,是否有类似于std::function的东西?
是的。有Boost.Function(boost :: function <>),它最近成为C ++标准库的一部分,并为std :: function <>提供了一个参考实现; 类似地,Boost.Bind(boost :: bind <>())被采用为标准,并变为std :: bind <>()。
它实现了一种称为类型擦除的技术,用于保存任何类型的可调用对象。以下是一个可能的、说明性的实现,展示了如何从头开始定义这样一个类模板(不要在生产代码中使用,这只是一个例子):
#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();
}

实际上,Boost 中的许多功能可以被视为“预标准”。 - leemes
不错的代码,展示了我们如何从头开始构建,但是你必须记住这是C++11。 ;) 我猜boost的实现要复杂得多(我猜他们会使用他们的预处理器库来完成?) - leemes
3
据我所知,“function”函数在tr1中也可用,它在C++11之前的大多数标准库中已实现,与“boost::function” 函数几乎相同。 - John5342
1
@leemes,我喜欢把Boost看作是“前卫”的...“预标准”让我想起了K&R C ;-) - rubenvb
1
@rubenvb:是的,还有一个事实就是在整合过程中对Boost库进行了一些更改。Boost是一种用于实验的沙盒,尽管其库具有高质量,但有时候只有在发布到公众后才能发现问题...这些问题可以在标准集成之前被修复/重新设计,以获得更好的标准。 - Matthieu M.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接