В предыдущей статье я описал как удобным образом описывать перегрузки функций по концептам, но не рассказал как удобно описывать концепты. Сейчас я хочу заполнить сей пробел.
В 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;
Комментариев нет:
Отправить комментарий