第五章 模板基础知识

1.关键字typename 关键字typename声明的是一个类型 示例代码如下

namespace Lee {
	class B {
	public:
	};
	class A {
	public:
		using Sub = B;

	};
	template<typename T>class C {
	public:
		typename T::Sub* ptr;//重点

	};
}

2.默认初始化 代码如下

void foo(){

int a;
int*ptr;}

c++会给内置类型例如指针,整数等等初始化一个默认值 还可以这么做

	template<typename T>
	class B {
	public:
		//B() :t{} {
		//
		//}
		T t;
	};
	template<typename T>
	class A {
	public:
		A() :b{} {//在c++17及之后可以用花括号的方式来初始化成员
		
		}
		B<T> b;
	};

注意事项: 1.不能用于初始化静态成员对象

template<typename T>class MyClass{
private:
T t{};//注意用于非静态对象
}

2.不能直接用于模板默认参数

template<typename T>void foo(T t{})//错误的
template<typename T>void foo(T t = T{});//正确的

3.使用this->

template<typename T>
	class A {
	public:
		A() = default;
		void f() {
			std::cout << "A" << std::endl;
		}

	};
	template<typename T>class B :public A<T> {
	public:
		B() = default;
		void func() {
			std::cout << "B func called" << std::endl;
			this->f();
			A<T>::f();//如果不采用这两种方式调用f,永远调用不了f函数
		}


	};

4.对于模板的数组和字符串使用 代码

	template<typename T,size_t size>
	void Array(const T(array)[size]) {
		std::cout << "value Array" << std::endl;
	}
	template<typename T,size_t size>
	void Array(const T(&array)[size]) {
		std::cout << "reference Array" << std::endl;
	}
	template<typename T>
	void Array(const T* array) {
		std::cout << "pointer" << std::endl;
	}
        //很奇怪,对于int a[5],Array(a)调用的都是引用版本,感觉像是编译器做的优化

5.成员模板

	class Member {
	public:
		Member() = default;
		template<typename T>void func(T t) {
			std::cout << "模板默认版本" << std::endl;
		}
	};
	template<> inline void  Member::func<std::string>(std::string s) {
		std::cout << "特化的std::string 版本" << std::endl;
	}
	template<> inline void Member::func<int>(int a) {
		std::cout << "特化的int 版本" << std::endl;
	}
        //类成员模板和函数模板一样只能全特化,不能偏特化,写法都一样
        //函数模板
        template<typename T>
	void func(T t) {
	}
	template<>inline void func<std::string>(const std::string s) {
	}

6.关于成员模板的概念

  1. 成员模板可以用于operator和构造函数,移动构造函数
  2. 拿构造函数举例,虽然声明了模板构造,但是并不会替代原来的构造函数

7.关于.template的使用 这个可以直接调用模板成员函数

	MEMBER::Member m;
	m.template func<int>(5);

8.模板变量 示例:

template<typename T>
constexpr T val{ 3.1415926 };//默认初始化的值

template<typename T>
T Value;

9.模板变量对于数据成员

	template<typename T>
	class A {
	public:
		static constexpr int a = 50;
	};
	template<typename T>
	int val = A<T>::a;

10.模板模板参数

	template<typename T, template<typename A, typename B = std::allocator<A>>class Cont = std::vector>class MVector {
	public:
		Cont<T> cont;
		template<typename T1,template<typename A,typename B = std::allocator<A>>class Cont1>
		MVector<T, Cont>& operator=(MVector<T1, Cont1>& t) {

		}
		template<typename ,template<typename,typename>class>
		friend class MVector;

	};