Consider the following code:
template< template< typename ... > class ... Ts >
struct unite
{
template< typename ... T >
struct type
: Ts< T ... > ...
{ };
};
// This does not work as ::type does not name a type, but a template:
// template< template< typename ... > class ... Ts >
// using unite_t = typename unite< Ts ... >::type;
template< typename > struct debug_none {};
template< typename > struct debug_cout {};
template< typename ... > struct raise_demangled {};
template< typename ... > struct raise_specialized {};
template< typename, typename = int > struct match_default {};
template< template< typename ... > class Control >
void f()
{}
int main()
{
f< unite< debug_none, raise_demangled, match_default >::type >();
// Is there any way to create something like unite_t which works like this:
// f< unite_t< debug_none, raise_demangled, match_default > >();
}
Live example
Question: Is there any way to create some kind of "template alias" similar to a type alias? (see unite_t
in the above example)
Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.
Type aliases create a new name for a type. Type aliases are sometimes similar to interfaces, but can name primitives, unions, tuples, and any other types that you'd otherwise have to write by hand.
Type alias is a name that refers to a previously defined type (similar to typedef). Alias template is a name that refers to a family of types.
Templates are powerful features of C++ which allows us to write generic programs. We can create a single function to work with different data types by using a template.
No, you cannot.
using
can "return" a type, or a variable. It cannot "return" a template
. There are no similar mechanisms elsewhere.
You can do something vaguely useful by taking the convention that all templates are not templates, but rather classes with a template<?>using apply=?;
alias inside them (and while we are at it, constants are std::integral_constants<T,?>
, and pointers are pointer_constant<T*,?>
).
Now everything is a class. template
s become just kinds of classes (with a ::apply<?...>
.
Applying a bundle of types to such a template would be done via:
template<class Z, class...Ts>
using apply_t = Z::template apply<Ts...>;
So with a "native" template Z
, you'd do Z<Ts...>
. With these "indirect" templates, you'd do apply_t<Z, Ts...>
.
With this convention, a template using
alias can return an indirect template. If the rest of your code follows the convention of always calling apply_t
to apply a template, and you indirect-ize all other templates you write, we are done.
This is ugly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With