Metafunction returning the tag associated to T
.
There are several ways to specify the tag of a C++ type. If it's a user-defined type, one can define a nested hana_tag
alias:
Sometimes, however, the C++ type can't be modified (if it's in a foreign library) or simply can't have nested types (if it's not a struct or class). In those cases, using a nested alias is impossible and so ad-hoc customization is also supported by specializing tag_of
in the boost::hana
namespace:
tag_of
can also be specialized for all C++ types satisfying some boolean condition using when
. when
accepts a single compile-time boolean and enables the specialization of tag_of
if and only if that boolean is true
. This is similar to the well known C++ idiom of using a dummy template parameter with std::enable_if
and relying on SFINAE. For example, we could specify the tag of all fusion::vector
s by doing:
Also, when it is not specialized and when the given C++ type does not have a nested hana_tag
alias, tag_of<T>
returns T
itself. This makes tags a simple extension of normal C++ types. This is super useful, mainly for two reasons. First, this allows Hana to adopt a reasonable default behavior for some operations involving types that have no notion of tags. For example, Hana allows comparing with equal
any two objects for which a valid operator==
is defined, and that without any work on the user side. Second, it also means that you can ignore tags completely if you don't need their functionality; just use the normal C++ type of your objects and everything will "just work".
Finally, also note that tag_of<T>
is always equivalent to tag_of<U>
, where U
is the type T
after being stripped of all references and cv-qualifiers. This makes it unnecessary to specialize tag_of
for all reference and cv combinations, which would be a real pain. Also, tag_of
is required to be idempotent. In other words, it must always be the case that tag_of<tag_of<T>::type>::type
is equivalent to tag_of<T>::type
.
Tip 1
If compile-time performance is a serious concern, consider specializing thetag_of
metafunction in Hana's namespace. When unspecialized, the metafunction has to use SFINAE, which tends to incur a larger compile-time overhead. For heavily used templated types, this can potentially make a difference.
Tip 2
Consider usingtag_of_t
alias instead oftag_of
, which reduces the amount of typing in dependent contexts.