Концепция<Constant>представляет данные, которыми можно манипулировать во время компиляции.
По своей сути,<Constant>— это просто обобщение принципа, лежащего в основе<std::integral_constant>, для всех типов, которые могут быть построены во время компиляции, т.е. для всех типов с конструктором<constexpr>(также называемымлитературными типами).. Более конкретно,<Constant>является объектом, из которого может быть получено значение<constexpr>(по<value>методу) независимо от<constexpr>ness самого объекта.
Все<Constant>должны быть несколько эквивалентны в следующем смысле. Пусть<C(T)>и<D(U)>обозначают метки<Constant>, удерживающие объекты типа<T>и<U>соответственно. Затем объект с тегом<D(U)>должен быть конвертируемым в объект с тегом<C(T)>всякий раз, когда<U>конвертируем в<T>, определяется<is_convertible>. Интерпретация здесь заключается в том, что<Constant>- это просто коробка, держащая объект определенного типа, и должна быть возможность поменяться между коробками, когда объекты внутри коробок могут быть заменены.
Из-за этого последнего требования может возникнуть соблазн думать, что специализированные «ящики», такие как<std::integral_constant>, не могут быть<Constant>, потому что они не могут удерживать объекты любого типа<T><std::integral_constant>. Это неверно; требование должно толковаться как указание на то, что всякий раз, когда<C(T)>имеет смысл(например, только тогда, когда<T>является неотъемлемой частью<std::integral_constant>исуществует преобразование из<U>в<T>, тогда также должно существовать преобразование из<D(U)>в<C(T)>. Точные требования для того, чтобы быть 23, воплощены в следующих законах.
Пусть<c>будет объектом с тегом<C>, который представляет собой<Constant>удерживающий объект с тегом<T>. Первый закон гарантирует, что значение обернутого объекта всегда является постоянным выражением, требуя, чтобы следующее было хорошо сформировано:
constexpr auto x = hana::value<decltype(x)>();
Это означает, что функция<value>должна возвращать объект, который может быть построен во время компиляции. Важно отметить, что<value>получает только тип объекта, а не сам объект. Это ядро концепции<Constant>; это означает, что единственная информация, необходимая для реализации<value>, должна храниться втипеее аргументации и, следовательно, быть доступной статически.
Второй закон, который должен быть удовлетворен, гарантирует, что<Constant>s в основном глупые коробки, что позволяет предоставлять модели для многих концепций без особой работы от пользователя. Закон просто требует, чтобы следующее выражение было действительным:
to<C>(i)
где<i>являетсяпроизвольным<Constant>, имеющим внутреннее значение с меткой, которая может быть преобразована в<T>, как определено метафункцией<hana::is_convertible>. Иными словами, когда<U>конвертируется в<T>,<Constant>, держащий<U>, конвертируется в<Constant>, держащий<T>, если такое<Constant>может быть создано.
Наконец, тег<C>должен обеспечивать вложенный<value_type>псевдоним<T>, что позволяет нам запрашивать тег внутреннего значения, удерживаемого объектами с тегом<C>. Другими словами, для любого объекта<c>с тегом<C>должно быть верно следующее:
В некоторых случаях<Constant>можно автоматически сделать моделью другого понятия. В частности, если<Constant><C>держит объект метки<T>, и если<T>моделирует концепцию<X>, то<C>может в большинстве случаев моделировать<X>, просто выполняя любую операцию, требуемую на его базовом значении, а затем обертывая результат обратно в<C>.
Если<Constant><C>имеет базовое значение<C::value_type>, которое является моделью<Comparable>,<Orderable>,<Logical>или<Monoid>до<EuclideanRing>, то<C>также должна быть моделью этих понятий. Другими словами, когда<C::value_type>моделирует одну из перечисленных концепций,<C>сам должен также моделировать эту концепцию. Тем не менее, обратите внимание, что для всех этих концепций предусмотрены бесплатные модели, поэтому дополнительная работа не должна проводиться.
Хотя теоретически можно было бы представить модели для таких понятий, как<Foldable>, на практике полезно иметь только пару понятий, таких как<Constant>. Предоставление бесплатных моделей для перечисленных выше понятий полезно, поскольку позволяет различным типам интегральных констант<std::integral_constant>,<mpl::integral_c>и т. д. ... легко иметь модели для них, просто определяя концепцию<Constant>.
Remarks
An interesting observation is that Constant is actually the canonical embedding of the subcategory of constexpr things into the Hana category, which contains everything in this library. Hence, whatever is true in that subcategory is also true here, via this functor. This is why we can provide models of any concept that works on constexpr things for Constants, by simply passing them through that embedding.
Кроме того, эти преобразования помечаются как встраивание всякий раз, когда преобразование базовых типов является встраиванием. Это позволяет константам легко взаимодействовать с объектами<constexpr>:
Строго говоря,это иногда является нарушениемтого, что значит быть вставкой. Действительно, в то время как существует встраивание от любой Константы к<constexpr>объекту (поскольку Константа является просто каноническим включением), нет встраивания от Константы к объекту времени выполнения, поскольку мы потеряли бы способность определять<value>метод (<constexpr>ness объекта был бы потерян). Поскольку невозможно отличить<constexpr>и не<constexpr>объекты по их типу, Хана не может знать, является ли преобразование<constexpr>объектом не. Иными словами, метод<to>не имеет возможности различать
constexpr int i = hana::to<int>(int_<1>);
который является составной частью и
int i = hana::to<int>(int_<1>);
которого нет. Чтобы быть на безопасной стороне, мы могли бы отметить преобразование как не-встраивание. Однако, если, например, преобразование из<integral_constant_tag<int>>в<int>не было помечено как встраивание, нам пришлось бы писать<plus(to<int>(int_<1>), 1)>вместо просто<plus(int_<1>, 1)>, что является громоздким. Следовательно, преобразование помечено как встраивание, но это также означает, что код, такой как
Он будет считаться действительным, что неявно утрачивает тот факт, что<int_<1>>является постоянным, и, следовательно, не следует обычным правилам для операций перекрестного типа в Хане.
Provided common data type
Из-за требования, что<Constant>s являются взаимозаменяемыми, когда их содержимое совместимо, два<Constant>s<A>и<B>будут иметь общий тип данных всякий раз, когда<A::value_type>и<B::value_type>имеют один. Их общий тип данных является неопределенным<Constant><C>таким, что<C::value_type>точно<common_t<A::value_type, B::value_type>>. Для отражения этого предусмотрена специализация<common>метафункции<Constant>.
Аналогично, общий тип данных также предоставляется от любой постоянной<A>до типа<T>, так что<A::value_type>и<T>имеют общий тип. Общий тип между<A>и<T>, очевидно, является общим типом между<A::value_type>и<T>. Как объяснялось выше в разделе о конверсиях, это иногда является нарушением определения общего типа, потому что должно быть встраивание в общий тип, что не всегда так. По тем же причинам, что и выше, этот общий тип все еще предоставляется.
Return the compile-time value associated to a constant.This function returns the value associated to a Constant. That value is always a constant expression. The normal way of using value on an object c is. More...
Equivalent to value, but can be passed to higher-order algorithms.This function object is equivalent to value, except it can be passed to higher order algorithms because it is a function object. value can't be passed to higher-order algorithms because it is implemented as an overloaded function. More...
Возврат значения времени компиляции, связанного с константой. Эта функция возвращает значение, связанное с<Constant>. Это значение всегда является постоянным выражением. Обычный способ использования<value>на объекте<c>.
constexpr auto result = hana::value<decltype(c)>();
Однако для удобства предусмотрена перегрузка<value>, чтобы ее можно было назвать:
Эта перегрузка работает, принимая<const&>к своему аргументу, а затем пересылая к первой версии<value>. Поскольку он не использует свой аргумент, результат все равно может быть постоянным выражением, даже если аргумент не является постоянным выражением.
Note
value<T>() is tag-dispatched as value_impl<C>::apply<T>(), where C is the tag of T.
hana::value is an overloaded function, not a function object. Hence, it can't be passed to higher-order algorithms. If you need an equivalent function object, use hana::value_of instead.
Example
// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
Это эквивалентно<value>, но может быть передано алгоритмам более высокого порядка. Этот объект функции эквивалентен<value>, за исключением того, что он может быть передан алгоритмам более высокого порядка, поскольку он является объектом функции.<value>не может быть передан алгоритмам более высокого порядка, поскольку он реализован как перегруженная функция.
Note
This function is a simple alias to value, and hence it is not tag-dispatched and can't be customized.
Example
// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
Статья Boost.Hana: Constant раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.