开发者

C++/Boost template runtime polymorphism

Not sure how to state subjec开发者_运维百科t clearly.

Suppose I have a bunch of functor classes which provide some method. Now I want to create a proxy class which will redirect the method call to one of the underlying functors.

eg:

template<class F>
class proxy_impl : proxy {
    F f;
    void method() { f.method(); }
};

template<>
class proxy_impl<void> {
    virtual void method() = 0;
};

class proxy {
    auto_ptr<proxy_impl<void> > *impl_;
    template<class F>
    proxy(F f) : impl_(new proxy_impl<F>(f)) {}    
    void method() {
        impl->method();
    }
};

What is this pattern called and does boost have implementation?

The reason for not having functors inherit directly is because functors can be something like a nameless lambda expression.

Ok, so it seems I need something like boost::any and boost::function functionality in one.


It looks like you're trying to re-invent object-based polymorphism... badly.

here'sow to do what you want

class interface { virtual void method()=0; }
class impl1 : public interface { void method(); }
class impl2 : public interface { void method(); }

...//example usage
interface i *;
if (cond) i = new impl1(); else i= new impl2();
i->method();//calls whichever implementing method was constructed.


Looks a lot like Boost.Function


As you suggest, this can be done with boost.any and boost.function. Specifically:

struct proxy {
  template <typename T>
  proxy(T t) : obj_(t) {
    method = [&obj_] { boost::any_cast<T&>(obj_).method(); }
  }
  boost::function<void()> method;
private:
  boost::any obj_;
};

If .method() is const, then you can do away with the boost::any, and just have the lambda capture the T object by value. In fact, in that case you could just do away with the proxy object and just use a bare boost::function.


I don't think I really understand.. It seems that all you want is to be able to chain functors together:

struct null_functor { void method() { }; };

template <typename F = null_functor>
struct functor1 {
  F f;
  void method() { 
    std::cout << "functor1 called!" << std::endl;
    f.method();
  };
};

template <typename F = null_functor>
struct functor2 {
  F f;
  void method() { 
    std::cout << "functor2 called!" << std::endl;
    f.method();
  };
};

int main() {
  functor1 f1;
  f1.method();

  functor1< functor1 > f11;
  f11.method();

  functor2< functor1 > f21;
  f21.method();

  return 0;
};

If you need dynamic binding on top of that, just make one functor be a base class with a virtual method, and derive other functors from it. You could use Boost.Bind as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜