C ++ / Boost шаблон времени исполнения полиморфизм - PullRequest
1 голос
/ 31 января 2011

Не уверен, как четко сформулировать тему.

Предположим, у меня есть несколько классов функторов, которые предоставляют какой-то метод. Теперь я хочу создать прокси-класс, который будет перенаправлять вызов метода на один из базовых функторов.

например:

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();
    }
};

Как называется этот шаблон и есть ли в boost реализация?

Причина, по которой функторы не наследуются напрямую, заключается в том, что функторы могут быть чем-то вроде безымянного лямбда-выражения.

Хорошо, похоже, мне нужно что-то вроде boost :: any и boost :: function в одном.

Ответы [ 4 ]

1 голос
/ 01 февраля 2012

Как вы предлагаете, это можно сделать с помощью boost.any и boost.function. В частности:

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_;
};

Если .method() является константой, то вы можете покончить с boost :: any, и просто лямбда-выражение захватывает объект T по значению. Фактически, в этом случае вы могли бы просто покончить с прокси-объектом и просто использовать голое повышение :: function.

1 голос
/ 31 января 2011

Очень похоже на Boost.Function

1 голос
/ 31 января 2011

Похоже, вы пытаетесь заново изобрести объектно-ориентированный полиморфизм ... плохо.

здесь, чтобы сделать то, что вы хотите

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.
0 голосов
/ 31 января 2011

Я не думаю, что я действительно понимаю .. Кажется, что все, что вы хотите, это иметь возможность соединять функторы вместе:

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;
};

Если вам нужно динамическое связывание, просто сделайте один функтор базовым классом с виртуальным методом и извлеките из него другие функторы. Вы также можете использовать Boost.Bind.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...