У меня есть разные типы view, каждый из которых имеет константу-член std::size_t View::dimension
и тип члена typename View::value_type
.
Следующая проверка типа компиляции должна проверить, являются ли From
и To
представлениями (проверено с помощью is_view<>
), а содержимое From
может быть назначено To
. (те же размеры и типы конвертируемых значений).
template<typename From, typename To>
struct is_compatible_view : std::integral_constant<bool,
is_view<From>::value &&
is_view<To>::value &&
From::dimension == To::dimension &&
std::is_convertible<typename From::value_type, typename To::value_type>::value
> { };
is_view<T>
таков, что он всегда оценивается как std::true_type
или std::false_type
для любого типа T
. Проблема в том, что если From
или To
не является типом представления, то From::dimension
(например) может не существовать, а is_compatible_view<From, To>
вызывает ошибку компиляции. Вместо этого в этом случае он должен оцениваться как std::false_type
.
is_compatible_view
используется для SFINAE с std::enable_if
для отключения функций-членов. Например, класс представления может иметь функцию-член
struct View {
constexpr static std::size_t dimension = ...
using value_type = ...
template<typename Other_view>
std::enable_if_t<is_compatible_view<Other_view, View>> assign_from(const Other_view&);
void assign_from(const Not_a_view&);
};
Not_a_view
не является представлением и вызывает ошибку компиляции в is_compatible_view<Not_a_view, ...>
. При вызове view.assign_from(Not_a_view())
SFINAE не применяется, и вместо этого возникает ошибка компиляции, когда компилятор пытается разрешить первую функцию assign_from
.
Как можно написать is_compatible_view
, чтобы это работало правильно? В С++ 17 позволяет ли std::conjunction<...>
это?