Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of `using` aliases for `template`s

C++11 added alias templates such as:

 template<typename T> using identity = T;
 template<bool b, typename T = void> using EnableIf = typename std::enable_if<b, T>::type;

These are much easier to use than the old template type maps that give you the return value in a ::type field because even if your type arguments are dependent on the local context, you don't need to inform the compiler that the result is a type.

In effect, you hoist the typename from the location of use to the using alias.

Is there anything equivalent that can be used to get rid of produced extraneous templates?

Suppose you had a metafunction whose output was a class or alias template instead of a type. The current method is something like this:

template<typename T>
struct my_meta {
  template<typename U>
  using Template = identity<U>;
};

template<typename T>
struct my_meta {
  template<typename U>
  using Template = int;
};

which we can then use like this:

template<typename T, typename U>
typename my_meta<T>::template Template<U>
do_stuff( U&& ) { return {}; }

That extra template keyword in the return type exists to disambiguate the return value of my meta function is what I want to eliminate.

Is there any way to indicate to the compiler that the result of a metacomputation is another alias or class template in C++11 or C++1y, without using the template keyword at the location of invocation?

Ie:

template<typename T, typename U>
my_meta_template<T><U>
do_stuff( U&& ) { return {}; }

or even

template<template<typename> class Template>
void do_more_stuff() {}

template<typename T>
void do_stuff() {
  // syntax I want: just produce an alias or class template directly:
  do_more_stuff< my_meta_template<T> >();
  // vs what I find is required: the disambiguator:
  do_more_stuff< my_meta<T>::template Template >();
};
like image 255
Yakk - Adam Nevraumont Avatar asked Jun 28 '13 02:06

Yakk - Adam Nevraumont


Video Answer


1 Answers

Best way I know to remove template is made simple warper that will do it for you:

template<typename Meta, typename U>
using apply = typename Meta::template Template<U>;

and every where you previously used template<typename> class Template replace it with typename Meta.

template<typename Meta>
void do_more_stuff()
{
    apply<Meta, int>::func(); //=== Meta::template Template<int>::func();
}

template<typename T>
void do_stuff() {
  do_more_stuff< my_meta<T> >();
  do_more_stuff< my_meta<T> >();
};
like image 194
Yankes Avatar answered Oct 07 '22 09:10

Yankes