Как я могу сделать класс независимым от типа его членов? - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть шаблонный класс

template <typename T> 
class Templated {
    T someValue;
    //... 
};

и другой класс с членом типа Templated.

class Holder {
    Templated t;
    //...
};

Это не скомпилируется, потому что фактический тип Holder::Templatedне известноЯ хочу, чтобы Holder::Templated был инициализирован / создан позже, его значение и тип будут считаны из файла конфигурации.Как я могу создать Holder объекты, но позже добавить фактические Holder::Templated члены?

Я мог бы иметь базовый класс для Templated и держать указатель базового класса в классе Holder, но я неМне не нравится этот вариант.Есть ли у вас какие-либо другие идеи о том, чтобы сохранить класс Holder, не зависящий от типа Templated члена?

Большое спасибо!

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

Шаблоны являются просто конструкцией полиморфизма времени компиляции.Вам нужен полиморфизм во время выполнения, который может быть достигнут различными способами в C ++:

  • Наследование + virtual функции: полезно, когда у вас есть интерфейс и открытый набор разработчиков;

  • std::variant: полезно, если у вас есть известный закрытый набор вариантов;

  • std::any: полезно, если вы хотите сохранить любой произвольный объект без каких-либо ограничений

  • Подробнее: std::function, dyno ,...

0 голосов
/ 20 ноября 2018

Если вы не хотите хранить указатель на базовый класс templated внутри держателя, вы можете добавить слой косвенности, и templated сам будет содержать указатель на его конкретную реализацию.

class Holder {
    Untemplated u;
    //...
};

class Untemplated {
    //...
     struct Templated_base {
        //... virtual interface
     };
     Templated_base* hook; // or better with smart pointers

     template <typename T>
     struct Templated : Templated_base {
        // ... final interface
     };

     template <typename T>
     Untemplated(T&& x) { hook = new  Templated<T>(std::forward<T>(x)); }
};

Это всего лишь приблизительный набросок тщательно разработанной стратегии, разработанной Шоном Родителем (см .: http://sean -parent.stlab.cc / paper-and-Presentations / # better-code-runtime-polymorphism ), который позволяет использовать динамический полиморфизм где-то, не платя цену везде.

0 голосов
/ 20 ноября 2018

Вы можете использовать std::any для хранения значения любого типа или std::variant для хранения значений из набора типов.Например:

#include <any>

class Holder {
    std::any t;
    //...
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...