В предыдущей статье я описал как удобным образом описывать перегрузки функций по концептам, но не рассказал как удобно описывать концепты. Сейчас я хочу заполнить сей пробел.
В Concepts Lite TS для описания требований, налагаемых концептом, зарезервированно ключевое слово requires. За неимением оного в современных компиляторах, мы попробуем добиться как можно более похожего поведения с помощью шаблонного типа который назовём require (отличаемся в одну букву, чтобы не ломать компиляцию после появления концептов в C++). А реализацию этого шаблона можно безбожно стырить, опять же, из семнадцатых плюсов, где в стандартной библиотеке появится тип void_t. Прочитав его описание несложно понять как описать концепт Wriable требующий наличия перегрузки оператора вставки в поток:
template<typename T, typename = require<>>
struct is_writable: public std::false_type {};
template<typename T>
struct is_writable<T, require<
decltype(std::declval<std::ostream&>() << std::declval<T>())
>>: public std::true_type {};
template<typename T>
using Writable = std::enable_if<is_writable<T>::value, T>::type
Где require это:
template<typename... T>
struct make_void {typedef void type;};
template<typename... T>
using require = typename make_void<T...>::type;
Комментариев нет:
Отправить комментарий