zoukankan      html  css  js  c++  java
  • c++ template

    一、模板函数

    #include <iostream>
    
    template <typename T>
    inline T const& max(T const& a, T const& b)
    {
        return a < b ? b : a;
    }
    
    template <typename TR,typename T1,typename T2> 
    inline TR add(T1 a, T2 b)
    {
        return a + b;
    }
    
    template <typename T1,typename T2> 
    auto sub(T1 a, T2 b)->decltype(a - b)
    {
        return a - b;
    }
    
    int main()
    {
        std::cout<<::max(5.5,1.3)<<std::endl;   //::表示全局名字空间,避免与 std 名>字空间里的 max 方法冲突
        std::cout<<::max<int>(5.5,1.3)<<std::endl;  //显式限定模板类型
        std::cout<<add<int>(5.5,1.3)<<std::endl;    //显式指定返回类型,其实与上面一样,是部分显式限定模板类型
        std::cout<<sub(5.5,1.3)<<std::endl;     //自动推导返回类型
    }

    在编译时,模板会被编译两次:
    第一次是在实例化之前,编译器会检查模板代码的语法问题。
    第二次是在实例化期间,编译器会检查是否所有的模板调用都有效(比如实例化类型不支持某些函数的调用等,此 max 例中就是传入的模板实参不支持 operator< 操作)。


    模板函数的重载:(包括与普通同名函数与模板特化函数)如果存在重载,优先选择普通函数,其次是特化函数,最后是通用模板函数,由特殊到一般。


    类模板的特化和局部特化、缺省模板实参。

    template<> class classname<T的特化类型> {...};

    template<typename T1> class classname<T2的特化实例> {...};


    非类型模板参数的限制:常整数(包括枚举值),或者指向外部链接对象的指针。

    模板内部的 typename 表示标识符可以是一个类型。

    .template 构造

    模板类继承后无法直接调用基类成员,需要使用this->修饰符来访问基类成员

    template <typename T>
    class Base
    {
    public:
        void exit();
    };
    template <typename T>
    class Derive:public Base<T>
    {
    public:
        void foo()
        {
            this->exit();
            //or
            Base<T>::exit();
        }
    };

    使用字符串作为模板参数需要注意:

    template <typename T1> template <typename T2> 
    inline T2 const& max (T const& a, T const& b)
    {
        return  a < b  ?  b : a;
    }
    
    int main()
    {
        std::string s;
    
        ::max<std::string>("apple","peach");   // OK: same type char[5]
    //    ::max("apple",s);         // ERROR: different types
    }

    成员函数的特化,不能在类里实现特化版本,甚至不能声明,只能在类外实现。

    如果在类外特化也不行(可能会在链接时报重定义错误),则放在 .cpp 文件中实现特化版本。

    #include <iostream>
    #include <string>
    
    struct User
    {
        template<typename T>
        T print()
        {   
            std::cout<<"print()"<<std::endl;
        }   
    
        //template<>
        //void print<int>()
        //  std::cout<<"print<int>()"<<std::endl;
        //} 
    };
    
    template<> int User::print<int>()
    {
        std::cout<<"print<int>"<<std::endl;
    }
    
    int main()
    {
        User u;
        u.print<int>();
    }

    模板非类型参数可以为 int,枚举,指针,函数指针:

    如:template<typename T,std::string(*func)(std::string)>  class Test{};

    参考:http://www.cnblogs.com/Clingingboy/archive/2011/03/08/1977372.html

  • 相关阅读:
    旅行计划(拓扑排序)
    Extended traffic
    Tram(最短路)
    Cow and Friend(贪心)
    Invitation Cards(SPFA + 反向建边)
    Johnny and Another Rating Drop(找规律)
    python连接服务器上传文件,后台执行命令
    linux杀死某个进程
    linux安装杀毒软件
    django项目同一用户不能同时登陆
  • 原文地址:https://www.cnblogs.com/tianyajuanke/p/3123503.html
Copyright © 2011-2022 走看看