实例化模板和未实例化模板的部分模板专业化

时间:2019-04-17 22:42:29

标签: c++ templates template-specialization partial-specialization

我有以下两个结构:

template<typename T>
struct one { /* ... */ };

template<template<typename...> typename T>
struct two { /* ... */ };

当我有这样的实例化实例/未实例化模板时:

template<typename T>
struct sample_templated { /* ... */ };

using instantiated = sample_templated<double>;

那我就可以做

one<instantiated>{};
two<sample_templated>{};

很好。我想合并onetwo的定义,以便它们具有相同的名称,因为这样可以递归。

我尝试使用默认定义,例如

template<typename...>
struct types_match_impl;

并且具有两个原始结构是其部分专业化,但这与two不兼容。

这里的解决方案是什么?

1 个答案:

答案 0 :(得分:3)

无法实现您希望的方式。原因如下:

one<instantiated>{};
two<sample_templated>{};

one的使用次数超过了two:它指的是instantiated实例化为{em> sample_templated的{​​{1}}。另一方面,double仅“使用” two

当您将模板视为类型上的函数时,这将变得更加清晰:sample_templated是一种接受(类型级别)函数来创建某种类型的函数。 two是一个接受类型以创建某种类型的函数:

one

以不同的方式输入one :: T -> one<T> two :: (T -> U) -> two<(T -> U)> 的参数与one的参数具有不同的“种类”(“ type of type”)。

您可以做什么:

  • 您可以提供two的特殊化,它接受模板模板参数(“类型级别函数”)的模板参数:

    one
  • 您可以将template<template<typename...> typename TT, typename T> struct one<TT<T>> { /* ... */ }; // this basically "calls" TT 变成可以接受两者的内容,尽管带有“虚拟”模板template参数:

    two

可能还有更多方法,但这取决于您的特定用例。