如何检测模板是否为别名模板

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

本文关键字:是否 别名 何检测 检测      更新时间:2023-10-16

给定一个"正常"模板:

template<typename> struct Normal;

和别名模板:

template<typename>
using Alias = void;

当作为模板模板参数给出时,我如何区分这两者?

因此,理想情况下,我希望编译以下内容:

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

一种可能的方法是利用它:

在推导模板模板参数

时,从不通过模板参数推导来推导别名模板。

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

因此,具有类似

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 {};

我们可以确定,当我们将Alias<int>作为第一个模板参数传递,Alias作为第二个模板参数传递时,编译器不会选择专用化。这立即为我们提供了:

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

有了这个,我们可以 - 给定一些合适的模板参数 - 检测模板是否是别名模板:

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, "");
}

这里的主要缺点当然是需要知道一组合适的模板参数。仅猜测(或使用int(不适用于例如具有固定数量(>1(模板参数的模板。

此外,这不适用于具有非类型(或模板(模板参数的(别名或非别名(模板。