Свойства, определяющие, совместим ли класс со std :: ostream & lt; & lt;

Я попытался реализовать type_traits, способный обнаружить, может ли класс использоваться в контексте такой инструкции, как: std::cout << my_class_instance;,

Моя реализация пыталась извлечь выгоду из SFINAE, чтобы определить, работает ли функция std::ostream& operator<<(std::ostream&, const MyClass&) доступно для класса. К сожалению, он не работает в g ​​++ — 4.9, который должен быть совместим с C ++ 11. Другие компиляторы не жалуются и, похоже, генерируют правильный код: g ++ — 5+, clang ++ — 3.3+, а также Visual Studio.

Вот реализация, которую я пробовал до сих пор:

#include <iostream>
#include <type_traits>
#include <vector>

template <class... Ts> using void_t = void;
template <class T, class = void> struct can_be_printed : std::false_type {};
template <class T> struct can_be_printed<T, void_t<decltype(std::cout << std::declval<T>())>> : std::true_type {};

static_assert(!can_be_printed<std::vector<int>>::value, "vector<int> cannot be printed");
static_assert(can_be_printed<int>::value, "int can be printed");

Живой пример доступен по адресу: https://godbolt.org/g/6xFSef .
Пожалуйста, не стесняйтесь, если вам нужно больше деталей.

2

Решение

Это проблема с тем, как gcc интерпретирует:

template <class... Ts> using void_t = void;

до того, как он решил проблему с основным языком, которая1558). По сути, gcc видит, что на этот псевдоним не влияют параметры шаблона, а просто помещается в void, Это полностью побеждает цель void_t если это всегда удается, то, что происходит в этом случае.

Вы можете обмануть это, просто оборачивая void_t в другом шаблоне (как предлагается в оригинальная бумага):

template <class... Ts> struct make_void { using type = void; };
template <class... Ts> using void_t = typename make_void<Ts...>::type;

Здесь gcc не может просто отбросить замену, поскольку, конечно, есть гипотетически некоторые другие make_void специализация, которая не только void,

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]