C++ type in value-level representation.
A type
is a special kind of object representing a C++ type like int
, void
, std::vector<float>
or anything else you can imagine.
This page explains how type
s work at a low level. To gain intuition about type-level metaprogramming in Hana, you should read the tutorial section on type-level computations.
hana::type
is implementation-defined. In particular, hana::type
may be a dependent type, so one should not attempt to do pattern matching on it. However, one can assume that hana::type
inherits from hana::basic_type
, which can be useful when declaring overloaded functions: hana::type
were defined naively, expressions like hana::type<T>{} == hana::type<U>{}
would cause both T
and U
to be instantiated. This is usually not a problem, except when T
or U
should not be instantiated. To avoid these instantiations, hana::type
is implemented using some cleverness, and that is why the representation is implementation-defined. When that behavior is not required, hana::basic_type
can be used instead.When storing type
s in heterogeneous containers, some algorithms will return references to those objects. Since we are primarily interested in accessing their nested ::type
, receiving a reference is undesirable; we would end up trying to fetch the nested ::type
inside a reference type, which is a compilation error:
For this reason, type
s provide an overload of the unary +
operator that can be used to turn a lvalue into a rvalue. So when using a result which might be a reference to a type
object, one can use +
to make sure a rvalue is obtained before fetching its nested ::type
:
Comparable
std::is_same
type trait. Hashable
hash
is the identity function on hana::type
s. Synopsis of associated functions | |
template<typename T > | |
constexpr type< T > | type_c {} |
Creates an object representing the C++ type T . | |
constexpr auto | decltype_ = see documentation |
decltype keyword, lifted to Hana. More... | |
constexpr auto | typeid_ = see documentation |
Returns a hana::type representing the type of a given object. More... | |
template<> | |
constexpr auto | make< type_tag > = hana::decltype_ |
Equivalent to decltype_ , provided for convenience. More... | |
constexpr auto | make_type = hana::make<type_tag> |
Equivalent to make<type_tag> , provided for convenience. More... | |
constexpr auto | sizeof_ |
sizeof keyword, lifted to Hana. More... | |
constexpr auto | alignof_ |
alignof keyword, lifted to Hana. More... | |
constexpr auto | is_valid |
Checks whether a SFINAE-friendly expression is valid. More... | |
Friends | |
template<typename X , typename Y > | |
constexpr friend auto | operator== (X &&x, Y &&y) |
Equivalent to hana::equal | |
template<typename X , typename Y > | |
constexpr friend auto | operator!= (X &&x, Y &&y) |
Equivalent to hana::not_equal | |
Public Member Functions | |
constexpr auto | operator+ () const |
Returns rvalue of self. See description. | |
|
related |
decltype
keyword, lifted to Hana.
decltype_
can be confusing, and hana::typeid_
should be preferred instead. decltype_
may be removed in the next major version of the library.decltype_
is somewhat equivalent to decltype
in that it returns the type of an object, except it returns it as a hana::type
which is a first-class citizen of Hana instead of a raw C++ type. Specifically, given an object x
, decltype_
satisfies
As you can see, decltype_
will strip any reference from the object's actual type. The reason for doing so is explained below. However, any cv
-qualifiers will be retained. Also, when given a hana::type
, decltype_
is just the identity function. Hence, for any C++ type T
,
In conjunction with the way metafunction
& al. are specified, this behavior makes it easier to interact with both types and values at the same time. However, it does make it impossible to create a type
containing another type
with decltype_
. In other words, it is not possible to create a type_c<decltype(type_c<T>)>
with this utility, because decltype_(type_c<T>)
would be just type_c<T>
instead of type_c<decltype(type_c<T>)>
. This use case is assumed to be rare and a hand-coded function can be used if this is needed.
The rules for template argument deduction are such that a perfect solution that always matches decltype
is impossible. Hence, we have to settle on a solution that's good and and consistent enough for our needs. One case where matching decltype
's behavior is impossible is when the argument is a plain, unparenthesized variable or function parameter. In that case, decltype_
's argument will be deduced as a reference to that variable, but decltype
would have given us the actual type of that variable, without references. Also, given the current definition of metafunction
& al., it would be mostly useless if decltype_
could return a reference, because it is unlikely that F
expects a reference in its simplest use case:
Hence, always discarding references seems to be the least painful solution.
|
related |
Returns a hana::type
representing the type of a given object.
hana::typeid_
is somewhat similar to typeid
in that it returns something that represents the type of an object. However, what typeid
returns represent the runtime type of the object, while hana::typeid_
returns the static type of the object. Specifically, given an object x
, typeid_
satisfies
As you can see, typeid_
strips any reference and cv-qualifier from the object's actual type. The reason for doing so is that it faithfully models how the language's typeid
behaves with respect to reference and cv-qualifiers, and it also turns out to be the desirable behavior most of the time. Also, when given a hana::type
, typeid_
is just the identity function. Hence, for any C++ type T
,
In conjunction with the way metafunction
& al. are specified, this behavior makes it easier to interact with both types and values at the same time. However, it does make it impossible to create a type
containing another type
using typeid_
. This use case is assumed to be rare and a hand-coded function can be used if this is needed.
Equivalent to decltype_
, provided for convenience.
|
related |
Equivalent to make<type_tag>
, provided for convenience.
|
related |
sizeof
keyword, lifted to Hana.
sizeof_
is somewhat equivalent to sizeof
in that it returns the size of an expression or type, but it takes an arbitrary expression or a hana::type
and returns its size as an integral_constant
. Specifically, given an expression expr
, sizeof_
satisfies
However, given a type
, sizeof_
will simply fetch the size of the C++ type represented by that object. In other words,
The behavior of sizeof_
is consistent with that of decltype_
. In particular, see decltype_
's documentation to understand why references are always stripped by sizeof_
.
|
related |
alignof
keyword, lifted to Hana.
alignof_
is somewhat equivalent to alignof
in that it returns the alignment required by any instance of a type, but it takes a type
and returns its alignment as an integral_constant
. Like sizeof
which works for expressions and type-ids, alignof_
can also be called on an arbitrary expression. Specifically, given an expression expr
and a C++ type T
, alignof_
satisfies
The behavior of alignof_
is consistent with that of decltype_
. In particular, see decltype_
's documentation to understand why references are always stripped by alignof_
.
|
related |
Checks whether a SFINAE-friendly expression is valid.
Given a SFINAE-friendly function, is_valid
returns whether the function call is valid with the given arguments. Specifically, given a function f
and arguments args...
,
The result is returned as a compile-time Logical
. Furthermore, is_valid
can be used in curried form as follows:
This syntax makes it easy to create functions that check the validity of a generic expression on any given argument(s).
f
is valid, one should use the is_valid(f)()
syntax. Indeed, is_valid(f /* no args */)
will be interpreted as the currying of is_valid
to f
rather than the application of is_valid
to f
and no arguments.