zoukankan      html  css  js  c++  java
  • 模板全特化与偏特化

    特化分为全特化与偏特化,全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。本质上,偏特化模板的匹配和选择过程与重载解析非常类似。实际上,在非常复杂的偏特化情况下,编译器可能就是将偏特化直接译成函数,然后直接调用重载解析来处理。重载解析和偏特化匹配都用到了模板参数推导。

    例如c++标准库中的类vector的定义
    template <class T, class Allocator>
    class vector { // … // };
    template <class Allocator>
    class vector<bool, Allocator> { //…//};
    这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。


    函数模板的偏特化
    严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
    template <class T> void f(T);  (a)
    根据重载规则,对(a)进行重载
    template < class T> void f(T*);  (b)
    如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。

     1 #include <iostream>
     2 #include <typeinfo>
     3 using namespace std;
     4 
     5 struct t1{}; struct t2{}; struct t3{};
     6 
     7 template <class A, int I> struct container
     8 {
     9    void callMe()
    10    {
    11       cout << "primary A: " << typeid(A).name() << " I: " << I << endl;
    12    }
    13 };
    14 
    15 template <class A1>  struct container<A1,25>
    16 {
    17    void callMe()
    18    {
    19       cout << "partial specialization " << typeid(A1).name() << " and 25 " << endl;
    20    }
    21 };
    22 
    23 template <> struct container<t3,99>
    24 {
    25    void callMe()
    26    {
    27       cout << "complete specialization t3, 99" << endl;
    28    }
    29 };
    30 
    31 
    32 int main(void)
    33 {
    34    container<t1,10> test1;
    35    test1.callMe();
    36    container<t3,99> test2;
    37    test2.callMe();
    38    container<t2,25> test3;
    39    test3.callMe();
    40    container<t3,25> test4;
    41    test4.callMe();
    42    return 0;
    43 }

    运行结果:

    在这个例子中有3个候选模板:

    模板1是带有两个模板参数的主模板,模板2是带有一个模板参数的偏特化模板,模板3是无模板参数的全特化模板。
    如前面所说,偏特化也仅是一个花哨的术语,偏特化模板中的模板参数没有被全部确定,需要编译器在编译时进行确定。
    当编译器编译执行到container<t3,25> test4,参数为<t3,25>:
    - 候选模板1,编译器可推导出 <A=t3, I=25>,故候选模板1有效;
    - 候选模板2,编译器为偏特化模板可推导出<A1=t3, 25>,故候选模板2有效;
    - 候选模板3, 编译器不可能从<t3,25>得到<t3,99>,故候选模板3被剔除。
    候选模板2是最匹配的模板,故匹配模板2。
  • 相关阅读:
    去掉[]中的英文字符
    Python面向对象OOP
    Python内置模块
    Python面向对象
    Python文件操作
    Python元组数据类型详解
    Jenkins+postman发送邮件测试报告及附件
    Python列表数据类型详解
    Python面向对象高阶描述符与设计魔术方法
    Python字典数据类型详解
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4420034.html
Copyright © 2011-2022 走看看