ostream для X, затем генерирование для необязательного <X>, unique_ptr <X>, shared_ptr <X>, возможно, вариант <X, Z> или вектор <X> - PullRequest
0 голосов
/ 13 ноября 2018

Учитывая тип X, который должен быть напечатан, я, естественно, реализую
std::ostream& operator<<(std::ostream& os, const X& x);

Если я хочу избежать повторения работы для различных оболочек, таких как std::optional<X>, std::unique_ptr<X>, std::shared_ptr<X> и т.д., каковы мои варианты?Есть ли библиотеки, которые уже реализуют это?Учитывая, что эти ключевые слова что-то вроде этого ужасно трудно найти, я смог найти закрытую библиотеку Информация о типе времени компиляции , которую я, вероятно, использовал бы для улучшения выходных данных optional и vector,но я хочу не изобретать велосипед.

1 Ответ

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

Таким образом, основная идея состоит в том, что вы добавляете шаблон operator<<, который смещает SFINAE в зависимости от типа возврата operator* объекта, который он передал.Примерно так:

template <typename T, typename Expected>
using deref_to = std::is_same<std::decay_t<decltype(*std::declval<T>())>, Expected>;

template <typename T, typename = std::enable_if_t<deref_to<T, X>::value>>
std::ostream& operator<<(std::ostream &os, const T &foo) {
    if(!foo)
        os << "{}";
    else
        os << *foo;
    return os;
}

Демо-версия , это работает даже для необработанных указателей.Не охватывает variant или vector, хотя это не должно быть слишком сложным для добавления.

Для обработки std::variant, std::tuple и std::pair вы, вероятно, сделаетето же самое, только с std::get<X> вместо operator*.

...