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::vectors 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_ofmetafunction 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_talias instead oftag_of, which reduces the amount of typing in dependent contexts.