C++ 模板

1.模板

模版分为:类模版、函数模版、成员函数模板。

1.1.类模板

用一个实例进行说明:

template<typename T>	// 类模板,
class complex{
private:
    T re, im;	// 模板
    friend complex& __doap1 (complex *ths, const complex& r); 	// 友元函数

public:
    complex(T r = 0, T i = 0) : re(r), im(i){}	// 默认参数、初始化列表
    complex& operate+=(const complex&);	// 重载运算符
    T real() const { return re; }		// 成员函数-常函数
    T imag() const { return im; }
};

int main(){
    complex<double> c1(1.1, 2.2);
    complex<int> c2(3, 4);
}

在类complex的定义前,加一个template:代表数据类型T是在声明对象的时候指定的,如complex c1(1.1, 2.2);指定了T为double类型。
注:template有时也写成template,它们是一样的,只是早期一般使用template

1.2. 函数模板

用一个实例进行说明:

#include <iostream>

// 函数模板
template<class T>
inline T& min(T& a,  T& b) {
	return b < a ? b : a;	// 运算符< 可被重载
}

class stone {
	private:
		int _w, _h, _weight;
	public:
		stone(int w, int h, int we) : _w(w), _h(h), _weight(we) {}
		// 重载运算符<
		bool operator <(const stone& rhs) {
			return this->_weight < rhs._weight;
		}

		int getWeight() {
			return _weight;
		}
};

int main() {
	stone r1(2, 3,5), r2(3, 3,1);
	// 调用模板函数min,类型推导
	// 类型推导T为stone类型,进一步调用stone::operator<()
	stone r3 = min(r1, r2);
	std::cout << r3.getWeight();

	return 0;
}

注:函数模板使用时,不必显式指定具体的泛型类型。编译器会对函数模板进行实参推导/类型推导(argument deduction)。类模板使用时,需显式指定具体的泛型类型。

1.3.成员函数模板

成员函数模板:类模板中的成员函数也为模板。举例如下:

#include<iostream>
using namespace std;
template <typename T>
 
class A {
public:

    A(T v):v(v){}

  template <typename U>
  void assign(const U& u)
  {
    v = u;
  }
  
  T getvalue()
  {
    return v;
  }
private:
  T v;
};

int main() {
	A<int> a(1);
    a.assign<int>(2);
    cout<< a.getvalue() << endl; // 输出2

	return 0;
}

【注】成员函数模板不能是virtual

模板构造函数:一种特殊的成员函数模板

#include <iostream>

template <typename T>
class A
{
public:
	template <typename U>
	A(const U& a) {
		std::cout << "template constructor" << std::endl;
	}

	A(const A& a) {
		std::cout << "copy constructor" << std::endl;
	}
	A() {
		std::cout << "default constructor" << std::endl;
	}
};

int main() {
	A<int> i; // default constructor
	A<int> ii(i); // implicitly generated copy constructor
	A<double> d(i); // template constructor

	std::cin.get();
	return 0;
}

结果为:

default constructor
copy constructor
template constructor

由于ii和i的类型是一样的,所以调用类A的拷贝构造函数A(const A& a) 对ii进行初始化。
由于d和i的类型是不一样的,所以调用A的模板构造函数 A(const U& a) 来对d进行初始化。其中U的类型为A。这就相当于A d(i)就实现了用类A初始化类A,也就是说实现了隐式的类型转换。
”ii和i的类型是一样时,调用类A的拷贝构造函数对ii进行初始化“,这就说明了A ii(i)没有调用模板构造函数 A(const U& a) ,而是调用了拷贝构造函数A(const A& a)。也就是说模板构造函数 A(const U& a)没有覆盖掉拷贝构造函数A(const A& a)的作用。

参考:链接1

posted @ 2022-05-07 16:57  好人~  阅读(341)  评论(0编辑  收藏  举报