Передача шаблонного класса с неизвестным типом в конструктор класса без шаблонов - PullRequest
2 голосов
/ 21 декабря 2010

У меня есть два класса, давайте назовем их SomeClass и OtherClass.

SomeClass является шаблоном:

template <typename T> class SomeClass
{
public:
    SomeClass (const T& value);
};

OtherClass не шаблонизирован, но использует SomeClass.

class OtherClass
{
public:
    OtherClass (const SomeClass& c, const std::string s);
};

Они должны называться следующим образом:

SomeClass<int> some(5);
OtherClass other(some, "hello, world!");

other.doSomethingWithSome();

... Очевидно, это не удастся скомпилировать, так как компилятор должен знать тип SomeClass '...

К сожалениюдля меня тип SomeClass может быть почти любым (хотя число используемых типов ограничено, просто не связано) и может часто меняться в процессе разработки. (Я знаю, я знаю, я полагаю, что я действительно мог бы использовать тип SomeClass и передать его шаблонному OtherClass, но это довольно утомительная работа, поскольку есть много примеров; кроме того, я хотел бы притворяться, что ни один классзнает о работе других. :))

Вопрос прост: как я могу использовать этот синтаксис?(Без необходимости шаблонизировать OtherClass.)

Ответы [ 5 ]

6 голосов
/ 21 декабря 2010

Очевидный ответ заключается в том, что вы можете SomeClass наследовать от не шаблонного абстрактного класса:

template <typename T>
class SomeClass : public SomeAbstractBase
{
    /* ... */
};

И, в свою очередь, OtherClass будет работать на SomeAbstractBase:

class OtherClass
{
public:
    OtherClass (const SomeAbstractBase& c, const std::string s);
};

Вы на самом деле не даете достаточно, чтобы точно сказать, что это в подходящем решении, но это может быть.В конце концов, если у вас нет проблем с написанием SomeAbstractBase (т. Е. Вам легко удается определить, что является общим для всех SomeClass<T>), то, возможно, это правильный путь.

3 голосов
/ 21 декабря 2010

Вы используете сокрытие типа:

class OtherClass
{
public:
  template < typename T >
  OtherClass(SomeClass<T> const& c, std::string const& s)
    : pimpl(new impl<T>(c))
    , str(s)
  {}

  void doSomething() { pimpl->doSomething(str); }

private:
  struct impl_base { virtual ~impl_base() {} virtual void doSomething(std::string) { ... }};
  template < typename T >
  struct impl : impl_base
  {
    impl(T const& )...
  };

  scoped_ptr<impl_base> pimpl;
};
1 голос
/ 21 декабря 2010

Вам нужно будет либо шаблонизировать OtherClass, либо специализировать конструктор OtherClass, чтобы принимать типы SomeClass, которые необходимо передать.

0 голосов
/ 21 декабря 2010

Используйте как время компиляции (шаблоны), так и полиморфизм времени исполнения (виртуальные):

class MyBase {
public: 
   virtual void foo() = 0;
}


template <class T>
class SomeClass : public MyBase {
public:

   void foo () {
     // do T-specific stuff
   }
}

OtherClass затем принимает MyBase* и OtherClass::doSomethingWithSome вызывает его виртуальный foo метод.

0 голосов
/ 21 декабря 2010

Не совсем понятно, что вы пытаетесь сделать.Но как насчет шаблонного конструктора?

class OtherClass {
public:
  template <typename T> OtherClass(const SomeClass<T>& c, const std::string& s);
  // ...
};

Конечно, это не сработает, если, например, OtherClass нужен член типа SomeClass<T>.

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