Определите, существует ли перегруженная функция, определенная для параметра определенного типа - PullRequest
0 голосов
/ 19 февраля 2019

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

std::vector<std::string> v{ "a1", "b123", "c12345" };
Read(stream, v);
Write(stream, v);

или

std::map<int, MyClass> m;
Read(stream, m);
Write(stream, m);

, например.

Я ищу способ определить во время компиляции тип, сериализуемый или нет, реализуя что-то вроде этого:

template <class T>
constexpr bool is_serializable()
{
    if (Read<T> and Write<T> are defined) 
        return true;
    return false;
}

или, возможно, что-то еще.

Возможно ли это?

Объявления чтения и записи:

    template <typename T>
    void Read(InputStream & s, T & val);

    template <typename T>
    void Write(OutputStream & s, T val);

теоретически я могу определитьis_serializable для каждого типа, который мне нужен в дополнение к Read и Write, но это требует большей типизации и, вероятно, усложняет код, поэтому автоматическое определение is_serializable является более элегантным способом.

Это также может быть некоторый класс шаблона Serializer.с функциями чтения и записи в качестве членов.В этом случае мне нужно знать, есть ли специализация Serializer для определенного типа.Например, я могу сделать с ним что-то вроде .

1 Ответ

0 голосов
/ 19 февраля 2019

Вы можете использовать std::void_t и SFINAE для достижения этой цели.Документация std::void_t в cppreference великолепна.

#include <type_traits>
#include <iostream>

void Read(std::istream &,double &) {}
void Write(std::ostream &,double) {}

template <typename T,typename= void>
struct is_serializable_t: std::false_type {};

template <typename T>
struct is_serializable_t<T,std::void_t<
    decltype(Read(std::declval<std::istream &>(),std::declval<T &>())),
    decltype(Write(std::declval<std::ostream &>(),std::declval<T>()))>>:
    std::true_type {};

template <typename T>
inline constexpr bool is_serializable = is_serializable_t<T>::value;

static_assert(is_serializable<double>);
static_assert(!is_serializable<int>);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...