2013-03-02 101 views
7

当C++ 11不可用时,应该使用什么构造作为std::function<>的代理?
替代方案应该基本上允许从下面的例子中访问另一个类的一个类的私有成员函数(不使用std :: function的其他功能)。 Foo类是固定的,不能改变太多,我只能访问类Bar。在C++ 11之前是否有类似于std :: function的东西?

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'无关;它不会破坏访问规则。 – 2013-03-02 17:37:24

回答

10

是否有类似的std之前C++ 11 ::功能的东西吗?

。有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(); 
} 
+0

事实上,来自助推的许多功能可以被视为“预标准”。 – leemes 2013-03-02 14:49:37

+0

不错的代码表明我们可以从头开始构建这个代码,但是您必须记住这是C++ 11。 ;)我猜boost实现要复杂得多(我猜他们使用它的预处理器库?) – leemes 2013-03-02 14:53:49

+0

@leemes:当然可以。我只是想或多或少提供实施原则的见解。这不仅仅是C++ 11,也是非常基础的。 – 2013-03-02 14:57:03

相关问题