Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I detect whether a template is an alias template?

Given a "normal" template:

template<typename> struct Normal;

and an alias template:

template<typename>
using Alias = void;

How can I, when given as template template parameter, differentiate between those two?

So, ideally I want the following to compile:

int main() {
  static_assert(  is_alias_template<Alias>::value, "");
  static_assert(! is_alias_template<Normal>::value, "");
}
like image 654
Daniel Jour Avatar asked Dec 01 '25 06:12

Daniel Jour


1 Answers

One possible approach is to exploit that:

Alias templates are never deduced by template argument deduction when deducing a template template parameter.

http://en.cppreference.com/w/cpp/language/type_alias

Thus, with a type trait like

template<
  typename T,
  template<typename...> class Template
  >
struct instantiated_from
  : std::false_type {};

template<
  template<typename...> class Template,
  typename... Arguments
  >
struct instantiated_from<Template<Arguments...>, Template>
  : std::true_type {};

we can be sure that when we pass Alias<int> as first template parameter and Alias as second, then the compiler won't choose the specialization. This immediately gives us:

template<
  template<typename...> class Template,
  typename... Args
  >
struct is_alias_template
  : std::integral_constant<
      bool,
      ! instantiated_from<Template<Args...>, Template>::value
      >
{};

With this we can - given some suitable template arguments - detect whether a template is an alias template or not:

int main() {
    static_assert(  is_alias_template<Alias, int>::value, "");
    static_assert(! is_alias_template<Normal, int>::value, "");

    static_assert(  is_alias_template<Alias, Alias<int>>::value, "");
    static_assert(  is_alias_template<Alias, Normal<int>>::value, "");
    static_assert(! is_alias_template<Normal, Alias<int>>::value, "");
    static_assert(! is_alias_template<Normal, Normal<int>>::value, "");
}

The main drawback here is of course that one needs to know a set of suitable template arguments. Just guessing (or using int) won't work for example with templates with fixed number (>1) of template parameters.

Further this doesn't work with (alias or not) templates that have non-type (or template) template parameters.

like image 173
Daniel Jour Avatar answered Dec 02 '25 22:12

Daniel Jour