C++模板笔记

    技术2022-05-12  30

    模板编程

     

    面向对象编程依赖的多态性是在运行时的,而模板依赖的多态性是编译时完成的。

     

     

    模板参数分为类型参数和非类型参数

    类型参数指的是一种具体的类型,而非类型参数指的是一个值,不是类型。

    比如

    template <typename T, int n>

    ....

    T 是类型参数,类型参数以typename或者class开头。

    n为非类型参数,非类型参数以具体的类型开始。

     

    使用函数模板

     

    编译器将推断出模板实参,然后将具体的类型替代类型参数,和值替代非类型参数,然后编译该版本。这个过程称为模板实例化。

     

    模板函数支持inline

    比如

     

    template<typename T > inline void func(){}

     

     

    类模板

     

    和定义函数模板一致,编译器在实例化时采取的动作是,将类型参数替代为具体的实参,然后编译。

     

     

    模板允许进行前置声明。

     

     

    一个例子

     

    template <typename Tp, int N>

    void array_init(Tp (&arr)[N])

    {

    }

     

    当使用

    int a0[10];

    array_init(a0);

    Tp 会被推导为int, N 被推导为10;

    注意上面的写法Tp (&arr)[N],这里有一个&。

    利用上面的写法,可以利用编译器来推导出一个数组的长度。

     

    在模板参数的实例化中,支持两种默认的类型转换

    1:const的转换,但要支持类型安全,不能将const的引用转为非const的引用

    2:数组或函数到指针的转换。

     

     

    模板实例化

    类模板实例化:

    编译器根据类得模板参数指定,在类得模板定义中,用模板实参替换掉形参,这样得到一个类得定义,然后编译器编译这个类。

     

    函数模板实例化

     

    函数模板实例化,则需要对函数调用时的实参进行类型推导,从而得到模板参数的实参。

     

    函数模板实例化得时候:

    1:函数的调用

    2:函数对函数指针的赋值,对于这种情况,对于函数模板实例化,他利用指定的函数指针的类型来推导模板参数。

    比如:

    template <typename T> int compare(const T&, const T&);

    ...

    int (*pf1) (const int&, const int&) = compare;

    这里他会推导T为int类型。

     

    类得实例化过程

     

    类在使用时被实例化,但是,他的成员函数,仅仅在被调用的时候才被实例化。如果一个成员函数从来没有被使用到,那么他不会被实例化。

    另外,使用类得指针不会引起实例化。因为这个是指针不需要知道具体指针类型,但是在使用的时候就会实例化了。

     

     

    Note that class template parameters are never duduced. The reason is that the flexibility provided by several constructors for a class would make such deduction impossible in many cases and obscure in many more.

     

    One common use of explicit specification is to provide a return type for a template function:

            template<typename T, typename U> T implicit_cast(U u){return u;}

     

    void g(int i)

    {

            implicit_cast<double>(i);

    Explicit specification of template arguments allows the definition of familise of conversion functions and object creation funcions.The syntax for dynamic_cast,static_cast matches the explicitly qualified template function syntax like above.

     

    Function Template Overloading

     

    1:find the set of function template specializations that will take part in overload resolution.

    2:If two template funcions can be called and one is more specialized than the other , consider only the most specialized template funcion in the following steps.

    3:Do overload resolution for this set of function, plus any ordinay functions as for ordinary funcions.(That is to say another instantiation will happen)If a tempalte funcion argument has been determined by template argument deduction, that argument cannot also have promotions, standard conversions, or user-defined conversions applied.(That is to say, the deduced type for the argument can't be cast to another type in instantiation except const and array to pointer.)

    4:If a funcion and a specialization are equally good matches, the function is preferred.

    5:If no match is found, the call is error.

     

    A function argument that is not involved in the deduction of a template parameter is treated exactly as an argument of a non-template function.

    for example:

    template<typename T, typename C> T get_nth(C& p, int n);

    the argument n is applied to all the rules of a argument of a non-template function.  

     

     

    A design method

     

    Using Template Arguments to Specify policy.

     

    The technique of supplying a policy through a template argument and then defaulting that argument to supply the most common policy is widely usesd in the stand library.

    For example, alloctor, .

     

    Specialization, User-Specialization

     

    User-Specialization proved successful in curbing code bloat in real use, because User-Specialization can minimize the code by maximizing the amount of shared code.

     

    Note:

    The general template must be declared before any specialzition.

    For example:

    template<typename T> class List<T*>{};

    template<typename T> class List{};//error,:general template after specializaion

     

    The critical information spplied by the general template is the set of template parameters that the user must supply to use it or any of its specializations.

    (so the general must before any specialization)

     

    Note:

    If you want to user-specilize a template, you should ensure there is no the same specialization existed;

    for example:

    template <class T> class List{};

    List<int*> li;

    template<class T> class List<T*> {};//error; List<int*> have been specialization.

     

     

    Order of specializations

     

    One Specialization is more specialized than another if every argument list that matches its specialization pattern also matches the other, but not vice versa. 

     

    For example

    template<class T> class Vector;        //general

    template<class T> class Vector<T*>;    //specialized

    template<> class Vector<void*>;        //more specialized

     

    Member Templates

     

    Note:

    A member template cannot be virtual .

     

    Inheritance Relationships

     

    a class template is sometimes called a type generator.


    最新回复(0)