C++ Learning 9

1) Member function template of ordinary class

class A
{
    
    
public:
    template<typename T> //类的成员函数模板,//成员函数模板和函数模板长得样子一样!
    void func(T tmp);
};

template<typename T>
void A::func(T tmp)
{
    
    
    cout << tmp << endl;
}

int main() 
{
    
    
    A a;
    a.func<double>(56.89);
    return 0;
}

2) Member function template of template class

template<class T2>
class A
{
    
    
public:
    A(T2 arg):arg_(arg){
    
    }
    template<typename T> //类的成员函数模板
    void func(T tmp);
private:
    T2 arg_;
};

//模板类的成员函数模板类外定义方法
template<class T2>
template<typename T>
void A<T2>::func(T tmp)
{
    
    
    cout << tmp + arg_ << endl;
}

int main() 
{
    
    
    A<int> a1(45);
    a1.func<int>(45); //output 90
    return 0;
}

3) Explicit instantiation of templates and explicit declarations.
The role of explicit instantiation: in order to prevent multiple .cpp files from generating the same class template and reduce system compilation overhead;
instantiate definitions and instantiate declarations!
template A; //In any one of multiple .cpp files, the instantiation definition [only one]
extern template A; //In other .cpp files, the instantiation declaration [can be multiple], represents This file does not need to be used in instantiation
4) using to define a template alias (the following case is a class template alias that defines a map container)
//using str_map_t = std::map<std::string, T> type;
//The above sentence, It is neither a function template nor a class template. It uses using to define a type alias, also called [type template];

template<class T>
using str_map_t = std::map<std::string, T>; //类型模板,也叫模板别名

int main() 
{
    
    
    str_map_t<int> m1;
    m1.insert({
    
    "abc",123});
    return 0;
}

4.1) Use typedef to redefine new types in template classes, but you cannot redefine a template! ! ! using can be used, the defined name is called type template;
template //The writing method before C++98
struct A
{ typedef std::map<string, T> mapType; //There must be a typedef, otherwise a compilation error will occur }; int main( ) { A::mapType a1; a1.insert({ “first”,23 }); return 0; }







//typedef int myint_t; //Use typedef to define an alias, just like defining a variable!!!
typedef int( func)(int, int);
using funcptr = int(
)(int, int); //With using definition How to write a function pointer
5) Display specified template parameters

template<class T1,class T2,class T3>
T1 func(T2 a, T3 b)
{
    
    
    return a + b;
}

int main() 
{
    
    
    //auto ret = func(3, 6);这样写不行,因为T1没有类型,必须显示指定;
    auto ret = func<int>(3, 6);
    cout << ret << endl;
    return 0;
}

6) Full specialization of class templates



说明:
	必须有泛化版本,才可以有特化版本!!!
 	特化版本优先被编译;

template<class T> //泛化版本
class A
{
    
    
public:
    bool compare(const T& tmp)
    {
    
    
        cout << "一般模板" << tmp << endl;
        if (tmp > 2.5) return 1;
    }
};

template<>
class A<float> //全特化版本,注意float绑定到类A上,注意写法!!!
{
    
    
public:
    bool compare(const float& tmp)
    {
    
    
        cout << "全特化" <<tmp << endl;
        if (tmp > 2.5) return 1;
    }
};

int main() 
{
    
    
    A<float> a;
    a.compare(4.7); //调用全特化版本
    A<int> a2;
    a2.compare(40); //泛化版本
    return 0;
}

7) Specialize member functions instead of templates



注意:特化成员函数就一个类,这是跟模板类特化的重要区别!!!
class A
{
    
    
public:
    template<typename T>
    void func(T tmp);
};

template<typename T> //成员函数的泛化版本
void A::func(T tmp)
{
    
    
    cout << "成员函数的泛化版本 " << tmp << endl;
}

template<> //成员函数的特化版本
void A::func(int tmp)
{
    
    
    cout << "成员函数的特化版本 " << tmp << endl;
}

int main() 
{
    
    
    A a;
    a.func<>(6); //调用的是特化版本
    a.func<float>(5.3); //调用的是泛化版本
    return 0;
}

8) Partial specialization of class templates (that is, local specialization)

//偏特化两方面:1)从模板参数数量上;2)模板参数范围上
template<class T,class U,class W>
class A //泛化类模板
{
    
    
public:
    A() {
    
     cout << "泛化版本 A constructor" << endl; }
    void func(void){
    
     cout << "泛化版本 func" << endl; }
};

template<class U,class W>
class A<int,U,W>
{
    
    
public:
    A() {
    
     cout << "偏特化版本1 A constructor" << endl; }
    void func(void) {
    
     cout << "偏特化版本1 func" << endl; }
};

template<class T, class W>
class A<T, float, W>
{
    
    
public:
    A() {
    
     cout << "偏特化版本2 A constructor" << endl; }
    void func(void) {
    
     cout << "偏特化版本2 func" << endl; }
};

int main() 
{
    
    
    A<char,int,int> a1; 
    a1.func();//调用的是泛化版本

    A<int, int, int> a2;
    a2.func();//调用的是特化版本1
    return 0;
}

9) The function template is fully specialized, and the function template has no partial specialization.






template<typename T,typename U>
void func(T a, U b)
{
    
    
    cout << "函数模板泛化 " << a + b << endl;
}

//以下5句代码用于不会执行!!!
template<typename T>
void func<T, double>(T a, double b) //函数模板偏特化,这是不可以的,编译不过去!!!!!!!!
{
    
    
    cout <<"函数模板偏特化--------------- "<< a + b << endl;
}

template<>
void func<double,double>(double a, double b) //必须有“<double,double>”,如果没有,则本质上是函数重载;
{
    
    
    cout << "函数模板全特化--- " << a + b << endl;
}


int main() 
{
    
    
    func<int,int>(3, 4.7); //调用的是泛化版本
    func<int,double>(4, 2.7);
    func<>(3.4, 5.6);//调用的是全特化版本
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_30143193/article/details/132443773
Recommended