如何读取模板部分专门化
How to read the template partial specialization?
假设如下声明:
template <typename T> struct MyTemplate;
以下部分专门化的定义似乎使用相同的字母T
来指代不同的类型。
template <typename T> struct MyTemplate<T*> {};
例如,让我们举一个具体的实例:
MyTemplate<int *> c;
现在,再次考虑上述部分专门化的定义:
template <typename T> struct MyTemplate<T*> {};
本行第一部分(即template <typename T>
), T
为int *
。在该行的第二部分(即MyTemplate<T*>
), T
是int
!
这样读:
-
主模板说明"
MyTemplate
是一个只有一个类型参数的类模板":template <typename> struct MyTemplate;
-
局部专门化表示,"只要存在类型
T
"…template <typename T>
…因此,
类型需要T *
"…MyTemplate
的专门化。struct MyTemplate<T *>
…
-
您还可以定义显式专门化。例如,可以说"每当为类型
X
请求专门化时,请使用以下替代定义:template <> struct MyTemplate<X> { /* ... */ };
注意,类模板的显式特化定义类型,而部分特化定义模板。
从另一个角度来看:部分类模板专门化推导出或模式匹配的类模板参数的结构:template <typename T> struct MyTemplate<T *>
// ^^^^^^^^^^^^ ^^^^^
// This is a new template Argument passed to the original class
// template parameter
这个新模板的形参名在结构上与原类模板的形参的实参进行匹配。
例子:
MyTemplate<void>
:类模板的类型参数为void
,主模板用于此特化MyTemplate<int *>
:类型参数为int *
。存在类型T
,即T = int
,因此请求的类型参数是T *
,因此模板的部分专门化定义用于此专门化。MyTemplate<X>
:参数类型为X
,并且为该参数类型定义了显式专门化,因此使用
专门化的正确阅读如下:
template <typename T> // a *type pattern* with a *free variable* `T` follows
struct MyTemplate<T*> // `T*` is the pattern
当模板由MyTemplate<int*>
实例化时,参数是与模式匹配的,而不是类型变量列表。然后从匹配中推导出类型变量的值。
template <typename T1, typename T2>
struct A;
及其专门化
template <typename T1, typename T2>
struct A<T1*, T2*>;
现在你可以把后者写成
template <typename T2, typename T1>
struct A<T1*, T2*>;
(变量列表顺序颠倒),这与前一个相同。事实上,列表的顺序是无关紧要的。当你调用A<int*, double*>
时,可以推断出T1=int
, T2=double
,无论模板头中T1和T2的顺序如何。
更进一步,你可以这样做
template <typename T>
struct A<T*, T*>;
并在A<int*, int*>
中使用它。现在很清楚,类型变量列表与实际的模板形参列表没有直接对应关系。
注意:术语"模式"、"类型变量"、"类型模式匹配"不是标准的c++术语。
你有这样一行:
MyTemplate<int *> c;
你的困惑似乎来自于假设< >
中的int *
以某种方式对应于template <typename T>
中的T
。但事实并非如此。在部分特化中(实际上在每个模板声明中),模板参数名只是"自由变量"(或者可能是"占位符")名称。模板参数(在您的例子中是int *
)不直接对应于这些,它们对应于模板名称后面的< >
中(或将是)的内容。
这意味着实例化的<int *>
部分映射到部分专门化的<T*>
部分。T
只是template <typename T>
前缀引入的一个名称。在整个过程中,T
为int
没有矛盾。T应该读作T, T*就是T*。
template <typename T> struct MyTemplate<T*> {};
"在这一行的第一部分(即template <typename T>
), T是int *。"
No -在template <typename T>
中T是整型,在struct MyTemplate<T*> {};
中T也是整型。
"注意,当使用部分专门化时,模板参数是从专门化模式推导出来的;template形参不仅仅是实际的模板实参。特别地,对于Vector<Shape*>
, T是Shape而不是Shape*。(Stroustrup c++,第4版,25.3,p. 732.)
- 是否可以对零模板参数进行模板专门化
- 如何用RISC-V GD32VF103CBT6开发板卸载精确的ADC过采样
- 如何将部分流作为参数传递
- 我是 c++ 的新手.学习基本知识后,我想做井字游戏.对于印刷板,我在下面写代码,但它显示错误
- 尝试根据类中 typedef 的存在来专门化模板函数
- HDF5Cpp 扩展复合数据集超板问题
- 如何基于模板化类的基类专门化成员函数
- 如何为指向复杂值的迭代器专门化算法?
- 有没有办法修改'operator->',以便'z->im'返回复数的虚部
- 专门化模板覆盖函数/避免对象切片
- 我能否根据其运算符()的签名专门化可变参数模板参数
- C++剪贴板队列粘贴随机结果?
- 将缓冲区复制到剪贴板 [换行错误]
- 如何使用模板化类专门化模板化函数?
- 如何删除部分类?
- 线程 std::调用未知类型,无法专门化函数错误
- 输入两个不专门化大小的矩阵
- 如何制作板1[{1,1}]='X';大学工作
- wxWidgets mac剪贴板在3.1.3上坏了?
- 部分类专门化只是编写完全专门化的另一种方式吗?