C++模板、泛化、特化

一、模板

1.1类模板(class template)

 

template<typename T>
class xxx
{

};

1.2函数模板(function template)

 

template <typename T>
void xxxx(T & x, T & y)
{
......
}

1.3成员模板(member template)

 

template <typename T>
class xxx
{
public:
  template <typename U>
  xxx(const U& a) {
    .......
  }
};

  泛化即全特化

二、特化

2.1模板偏特化(局部特化)

2.1.1个数的偏

 

template<typename T, typename V=....>
class xxx
{
    ......
};



// 上面T绑定为bool
template<typename V=....>
class xxx<bool, V>
{
    ......
};

2.1.2范围的偏

// =================一==========================
template<typename T>
class xxx
{
    ......
};
// =============================================


// =================二==========================
// 模板范围指定在指针类型的偏特化
template<typename T>
class xxx<T*>
{
    ......
};
// =============================================

// 例子
xxx<string>  obj1;  //用的是类模板的全特化,任意类型用代码一
xxx<string*> obj2;  //用的是指针类型偏特化,指针类型用代码二

三、模板模板参数(template template parameter)

template<typename T, 
         template<typename T>
              class Container
         >

class YYY
{
private:
    Container<T> c;

    ......
};



// 例子
template<typename T>
using MyList = list<T, allocator<T>>;

YYY<string, list>  mylst1;  // 错误
YYY<string, MyList>  mylst2;  // 正确

四、可变的模板参数(variadic templates [C++11])

     可变的模板参数即是:数量不定的模板参数

void print()
{
    ......
}


template<typename T, typename... Types>
void print(const T& firstArg, const Types&... args)
{
    cout << firstArg << endl;
    // 递归自己,args数据打印完后就没有参数了就调用最上面的没有参数的print
    print(args...);  
}

上面代码typename... Types中的...就是一个pack(包)

用于template parameters, 就是template parameters pack(模板参数包)

用于function parameter types, 就是function parameter types pack(函数参数类型包)

用于function parameters, 就是function parameters pack(函数参数包)

如果想要知道args里有多少个参数,可以用C++语言的操作符sizeof...(args)求得

实例:字符串输出

#include <iostream>
using namespace std;

void show(const char* str)
{
	cout << str;
}

template<typename T, typename...Args>
void show(const char* str, T t, Args... args)
{
	while (str && *str) // 指针且字符不为空
	{
		if (*str== '%' && *(str+1)!='%')
		{
			++str; // 指针移动
			cout << t;	// 打印
			show(++str, args...); // 递归继续调用
			return;
		} 
		else
		{
			cout << *str++; // 跳过一个字符
		}
	}
}


int main()
{
	show("%d  %f hello %%   world! %s %c hello world!", 1, 1.1, "hello", 'A');	
	return 0;
}

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页