(Based in part on https://ericniebler.github.io/meta/index.html, designed to be a printable quick reference.)
Using the C++14 standard library.
- Trait:
std::add_pointer
- is a "template" (has template parameters) - not a type unless evaluated.
- Evaluate:
typename std::add_pointer<int>::type
(akatypepack::t_<std::add_pointer<int>>
) isint *
- Alias (alias template):
std::add_pointer_t
- is a "template" (has template parameters) - not a type unless evaluated.
- application:
std::add_pointer_t<int>
isint *
- Alias class:
meta::quote<std::add_pointer_t>
ormeta::quote_trait<std::add_pointer>
orstruct add_pointer_class { template<typename T> using apply = std::add_pointer_t; };
- is a type (not a template) for easy passing to algorithms, with a nested alias template.
- application: given one of the above with the name
add_pointer_ac
,typepack::apply<add_pointer_ac, int>
isint *
Type aliases are these things:
using StringVec = std::vector<String>;
C++11, more consistent syntax for typedefs. (mirrors usage of auto, etc.)
Alias templates are the above except with one or more free template arguments:
template<typename... Args>
using PointlessVecWrapper = std::vector<Args...>;
// As seen in C++14
template<typename... Args>
using enable_if_t = typename enable_if<Args>::type;
Importantly, naming them "returns" the "value" - no nested type
required.
Alias templates are the main "function" type in meta and typepack, unlike MPL where "metafunctions" aka "traits" primary.
Unless otherwise specified, alias refers to alias template.
Traits are class templates that have a nested type alias called type
,
like this boring one that always "returns" void
no matter the argument(s).
template <typename... Args>
struct t
{
using type = void;
};
(These are what the MPL calls metafunctions, except they'd probably
have a typedef void type
instead of the newer type alias syntax using type = void
.)
You can evaluate traits either with typename whatever<args>::type
or the cleaner typepack::t_<whatever<args>>
.
(meta uses meta::_t
to mimic the C++14 practice of providing aliases for all traits, ending in _t
, but
that's technically a not-permissible name. This is probably one of the largest porting differences between typepack and meta.)
Alias classes are for "higher-order" metaprogramming:
since the primary function abstraction takes template args (that is, it's not a type),
they can be a pain to pass around - not as easy as passing a type.
Alias classes are (non-templated!) classes with a nested alias template named apply
.
struct ac
{
template <typename... Args>
using apply = void;
};
They're a way to pass "functions" as arguments to algorithms (like transform
, fold
, etc.)
To evaluate them, use the alias template typepack::apply
like typepack::apply<ac, arg1, arg2>
- Evaluate:
- Alias: name them with arguments.
- Trait:
typepack::t_<yourtrait<yourargs>>
- Alias class:
typepack::apply<ac, arg1, arg2>
- Conversions:
- Alias (alias template) to alias class:
typepack::quote<youralias>
- Trait (that is, nested
type
name) to alias class that handles evaluating the trait:typepack::quote_trait<yourtrait>
- Alias (alias template) to alias class: