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 > >();
}
Question: Is there any way to create some kind of "template alias" similar to a type alias? (see unite_t
in the above example)
No, you cannot.
using
can "return" a type, or a variable. It cannot "return" atemplate
. 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 arestd::integral_constants<T,?>
, and pointers arepointer_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:
So with a "native" template
Z
, you'd doZ<Ts...>
. With these "indirect" templates, you'd doapply_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 callingapply_t
to apply a template, and you indirect-ize all other templates you write, we are done.This is ugly.