Существует несколько способов указать тег типа C++. Если это тип, определяемый пользователем, можно определить вложенный<hana_tag>псевдоним:
struct MyUserDefinedType {
using hana_tag = MyTag;
};
Иногда, однако, тип C++ не может быть изменен (если он находится в иностранной библиотеке) или просто не может иметь вложенные типы (если это не структура или класс). В этих случаях использование вложенного псевдонима невозможно, поэтому специальная настройка также поддерживается специализацией<tag_of>в пространстве имен<boost::hana>:
<tag_of>также может быть специализирована для всех типов C++, удовлетворяющих некоторым условиям булевой системы.<when>.<when>принимает однократный булеан и позволяет специализироваться на<tag_of>, если и только если этот булеан<true>. Это похоже на хорошо известную C++ идиому использования фиктивного параметра шаблона с<std::enable_if>и полагаясь на SFINAE. Например, мы можем указать тег всех<fusion::vector>s, сделав:
Также, когда он не является специализированным и когда данный тип C++ не имеет вложенного<hana_tag>псевдонима,<tag_of<T>>возвращается<T>сам. Это делает теги простым расширением обычных типов C++. Этосуперполезно, в основном по двум причинам. Во-первых, это позволяет Хане принимать разумное поведение по умолчанию для некоторых операций с использованием типов, которые не имеют понятия тегов. Например, Хана позволяет сравнивать с<equal>любые два объекта, для которых определен действительный<operator==>, и которые без какой-либо работы на стороне пользователя. Во-вторых, это также означает, что вы можете полностью игнорировать теги, если вам не нужна их функциональность; просто используйте обычный тип C++ ваших объектов.
Наконец, также обратите внимание, что<tag_of<T>>всегда эквивалентно<tag_of<U>>, где<U>является типом<T>после удаления всех ссылок и cv-калификаторов. Это делает ненужным специализацию<tag_of>для всех эталонных комбинаций, что было бы настоящей болью. При этом<tag_of>он должен быть уравновешенным. Иными словами, всегда должно быть так, что<tag_of<tag_of<T>::type>::type>эквивалентно<tag_of<T>::type>.
Совет 1 Если производительность компиляции является серьезной проблемой, рассмотрите возможность специализации метафункции<tag_of>в пространстве имён Ханы. При неспециализации метафункция должна использовать SFINAE, который имеет тенденцию нести большие накладные расходы на компиляцию. Для широко используемых шаблонных типов это потенциально может иметь значение.
Совет 2 Рассмотрите возможность использования псевдонима<tag_of_t>вместо<tag_of>, что уменьшает количество ввода в зависимых контекстах.
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: boost::hana::tag_of< T, enabler > Struct Template Reference раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.