Есть шаблонный класс:
template <typename T>
class CSerializer {
public:
void write(std::ostream &stream, const T &value) const;
void read(std::istream &stream, T &value) const;
};
Предполагается, что инстанцирование объектов данного класса будет выполняться только для PDT типов (int, unsigned, char и т.п.).
Для остальных типов предполагается наличие специализаций данного класса, например, для типа std::string
:
template <>
class CSerializer<std::string> {
public:
void write(std::ostream &stream, const std::string &str) const;
void read(std::istream &stream, std::string &str) const;
};
Далее. У нас есть интерфейс ISerializable
:
class ISerializable {
public:
virtual ~ISerializable() = default;
public:
virtual void write_binary(std::ostream &stream) const = 0;
virtual void read_binary(std::istream &stream) = 0;
virtual size serialized_size() const noexcept = 0;
};
, а так же множество классов, которые от него наследуются. Я хотел специализировать класс CSerializer
для типа ISerializable
, вроде:
template <>
class CSerializer<ISerializable> {
public:
void write(std::ostream &stream, const ISerializable &obj) const;
void read(std::istream &stream, ISerializable &obj) const;
};
И это не заработало :) Почему не заработало - я понимаю. Вопрос: можно ли написать такую специализацию класса CSerializer
, которая бы инстанцировалась, когда T - класс-наследник ISerializable
?
Я знаю как это сделать через ф-ию, вроде:
template <typename T, typename Enable = void>
CSerializer<T>* make_serializer() { ... }
template <typename T, typename std::enable_if<std::is_base_of< ... >>::value>
CSerializer<ISerializable>* make_serializer() { ... }
Но пусть это будет "запасным" вариантом.
UPD: подсказали, что в C++20 для этого идеально подходят концепты. Создал еще один вопрос.
Все точно так же, как с функцией:
template <typename T, typename Void = void>
class CSerializer
{
static_assert(std::is_void_v<Void>);
...
};
template <typename T>
class CSerializer<T, std::enable_if_t<std::is_base_of_v<ISerializable, T>>>
{
...
};
ну как вариант, можно сделать:
template<typename _T>
using SerializerType = CSerializer<typename std::conditional<std::is_base_of<ISerializable, _T>::value, ISerializable, _T>::type>;
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как сгенерировать значения, допустим от 10000 до 99999? Используя Mathrandom() проскакивают четырех-,шести- значные
Есть массив заполненный числами от 1 до 100 с пропущенным числом 46, путем сложения первого и последнего элемента идет поиск пропущенного элемента,...
В приложении есть чекбокс, и если пользователь устанавливает галочку то мы должны считать цену чашки кофе не по 5$, а по 6$
Есть код для добавления позиции в массив: