Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a template alias?

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)

like image 921
Daniel Frey Avatar asked Mar 12 '15 20:03

Daniel Frey


People also ask

What is an alias template?

Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.

What are type aliases?

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.

What is type alias in C++?

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.

What is function template C++?

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.


1 Answers

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.

like image 83
Yakk - Adam Nevraumont Avatar answered Sep 19 '22 03:09

Yakk - Adam Nevraumont