Is it possible to create a template alias?

2020-07-03 03:12发布

问题:

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)

回答1:

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. templates 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.