函数模板和类模板:
模板—泛型编程 —和重载一样都是在编译时实现–静态多态 编译时推导,最终生成几个函数不确定,消耗时间,模板技术掌握比较困难 C++文件过程:预处理(.i)-编译(.s)-汇编(.o)-链接(.out/.exe) 优点:提高开发效率 STL,容器,算法,迭代器都使用到模板 模板概念:
模板函数: template void add(T a,T b){
} 模板函数特化 template T add(int a,T b){
} //全特化 template<> int add(int a,int b){
}
int add(int a,int b){
cout<<"call common add"<<endl;
return a+b;
}
template<class T>
T add(T a,T b){
return a+b;
}
add<int>(1,2);
add<int>(1,2.0f);
template<class T,class U>
T add(T a,U b){
return a+b;
}
add<int>(1,2);
add<int>(1,2.0f);
cout<<"add(1.2f,2)"<<add(1.2f,2)<<endl;
cout<<"add(1.2f,2)"<<add(2,1.2f)<<endl;
add<int,float>(1.2f,2)<<endl;
class Point{
public:
int operator+(const Pointt& p){
return 0;
}
};
template<class T,class U>
auto add(T a,U b)->decltype(a+b){
cout<<"123"<<endl;
return a+b;
}
add<int>(1,2);
add<int>(1,2.0f);
cout<<"add(1.2f,2)"<<add(1.2f,2)<<endl;
cout<<"add(1.2f,2)"<<add(2,1.2f)<<endl;
add<int,float>(1.2f,2)<<endl;
decltype()
decltype(2+3.0f)n;
typeid(n).name()
Point p1,p2;
decltype(p1+p2)p;
typeid(p).name()
template<class T>
void swap(T&&a,T&&b){
T c=a;
a=b;
b=c;
}
不定参模板
namespace master{
T sum(T t){
return t;
}
template<class T,class ...ARGS>
T sum(T t, ARG ...args){
return t+sum(args...);
}
}
int main(){
master::sum(1,2,3,4,5,6,7,3,4,3);
return 0;
}
类模板:
模板类和模板类的特化
#include <iostream>
using namespace std;
namespace master{
template<class T>
class print{
public:
print(){}
print(int n){}
template<class U>
print& operator()(U u){
cout<<u<<" ";
return *this;
}
};
template<>
class print<int>{
public:
print(int n){}
template<class U>
print& operator()(U u){
cout<<u<<" ";
return *this;
}
};
};
int main(){
master::print<void>print;
print(1)("kkb")(445566)("5.0f");
master::print<int>(1)("kkb")(445566);("5.0
return 0;
}
元编程:
编程范式上说是函数式编程,用递归形式实现循环功能,用C++的模板特化提供了条件判断能力,元数据等->使其具备图灵完备性
图灵完备性: 1.基本的数据类型 2.可以用某种方式组合基本数据类型实现更高级的数据类型 3.需要流程控制 4.需要输入输出 具备上述特性,可以写出满足任何需求的程序
编译时已计算好
template<int M,int N>
struct Meta_Sum{
static const int value=M+N;
}
template<int N>
struct MySum{
static const int value=M+MySum<N-1>::value;
}
template<>
struct MySum<1>{
static constexpr int value=1;
}
string AreaCode(int code){
switch(case){
case 10:
return "beijing";
case 21:
return "shanghai";
}
}
template<int code>
struct metaAreaCode{
static constexpr char*value="zhongguo";
};
template<>
struct metaAreaCode<10>{
static constexpr char*value="zhongguo1";
};
template<>
struct metaAreaCode<21>{
static constexpr char*value="zhongguo2";
};
int main(){
cout<<Meta_Sum<199,200>::value<<endl;
MySum<100>::value;
metaAreaCode<10>::value<<endl;
return 0;
}
IFELE<true,int,double>::type a;
template<bool b,class IF,class ELSE>
struct IFELSE{
using type=void;
};
template<class IF,class ELSE>
struct IFELSE<true,IF,ELSE>{
typedef IF type;
};
template<class IF,class ELSE>
struct IFELSE<false,IF,ELSE>{
typedef ELSE type;
};
template<int n,class T,class ...ARGS>
struct ARG{
using type= typename ARG<n-1,ARG...>::type;
};
template<class T,class ...ARGS>
struct ARG<0,T,ARGS...>
{
using type=T;
};
ARG<0,int ,double,float,char,long>::type a1;
constexptr:
template<class T>
void speak(T t){
if constexpr(std::is_name<T,PersonA>{}){
t.speakEnglish();
}else if constexpr(std::is_name<T,PersonB>{}){
t.speakChinese();
}
}
class Person{
public:
static void speak(void*person){
if(std::is_name<decltype(person),PersonA*>::value){
((PersonA*)person)->speakEnglish();
}else if(std::is_name<decltype(person),PersonB*>::value)
((PersonB*)person)->speakChinese();
}
}
template<class T>
void speak(T t){
if constexpr(std::is_name<T,PersonA>{}){
t.speakEnglish();
}else if constexpr(std::is_name<T,PersonB>{}){
t.speakChinese();
}
}
Vector模板简易实现:
#include <iostream>
#include <vector>
using namespace std;
class Point
{
public:
Point() :_x(0), _y(0) {
}
Point(float x) :_x(x), _y(x) {
}
Point(float x, float y) :_x(x), _y(y) {
}
Point(const Point& p) :_x(p._x), _y(p._y) {
cout << "Point Copy Constructor!" << endl;
}
void operator=(const Point& p) {
_x = p._x;
_y = p._y;
cout << "Point Operator = !" << endl;
}
inline float getX()const { return _x; }
inline float getY()const { return _y; }
private:
float _x, _y;
};
namespace master {
template<class T>
class vector {
public:
class iterator {
private:
vector<T>* pVector;
size_t pos;
public:
iterator(vector<T>* vector, size_t offset = 0) :pVector(vector), pos(offset) {
}
bool operator!=(const iterator& it) {
return !(pos == it.pos);
}
iterator& operator++() {
++pos;
return *this;
}
iterator operator++(int) {
iterator it(pVector, pos);
pos++;
return it;
}
iterator& operator+=(size_t offset) {
pos += offset;
return *this;
}
iterator operator+(size_t offset) {
return iterator(pVector, pos + offset);
}
iterator operator-(size_t offset) {
return iterator(pVector, pos - offset);
}
iterator& operator--() {
--pos;
return *this;
}
iterator operator--(int) {
iterator it(pVector, pos);
pos--;
return it;
}
iterator& operator-=(size_t offset) {
pos -= offset;
return *this;
}
T& operator*() {
return (pVector->_begin[pos]);
}
T* operator->() {
return pVector->_begin[pos];
}
T& operator[](size_t offset) {
return *pVector->_begin[offset];
}
};
private:
T* _begin;
T* _end;
T* _capacity;
public:
vector() :_begin(nullptr), _end(nullptr), _capacity(nullptr) {
}
vector(size_t size, const T& value = T()) :_begin(nullptr), _end(nullptr), _capacity(nullptr) {
reserve(size);
while (size--)
{
*_end = value;
_end++;
}
}
vector(const master::vector<T>& vec) :_begin(nullptr), _end(nullptr), _capacity(nullptr) {
if (this == &vec) return;
reserve((size_t)vec.capacity());
for (int i = 0; i < vec.size(); i++) {
*_end = *(vec._begin + i);
_end++;
}
}
vector(master::vector<T>&& vec) {
std::swap(this->_begin, vec._begin);
std::swap(this->_end, vec._end);
std::swap(this->_capacity, vec._capacity);
}
~vector() {
if (_begin) delete[] _begin;
}
master::vector<T>& operator=(vector<T> vec) {
swap(*this, vec);
return *this;
}
T& operator[](size_t index) {
return *(_begin + index);
}
void swap(master::vector<T>& vec) {
std::swap(this->_begin, vec._begin);
std::swap(this->_end, vec._end);
std::swap(this->_capacity, vec._capacity);
}
void push_back(const T& value) {
if (_end == _capacity) {
size_t len = size();
if (len == 0) len = 1;
else len = len * 2;
reserve(len);
}
if (_end == nullptr) {
_end = _begin;
}
*_end = value;
_end++;
}
void pop_back() {
_end--;
}
void reserve(size_t n) {
cout << "reserve -- n = " << n << " capacity = " << capacity() << endl;
if (n > capacity()) {
size_t count = size();
T* p = nullptr;
if (_begin) {
p = (T*)realloc(_begin, n * sizeof(T));
if (p == nullptr) {
printf("realloc fail\n");
}
else {
printf("realloc %p %p\n", p, _begin);
}
}
else {
p = (T*)malloc(n * sizeof(T));
}
_begin = p;
_end = p + count;
_capacity = _begin + n;
cout << _begin << " " << _end << endl;
}
}
public:
size_t size() const {
return _end - _begin;
}
size_t capacity() const {
return _capacity - _begin;
}
inline iterator begin() { return iterator(this); }
inline iterator end() { return iterator(this, size()); }
};
}
template<typename T>
ostream& operator<<(ostream& os, const std::vector<T>& arr) {
for (auto data : arr)
os << data << " ";
return os;
}
template<typename T>
ostream& operator<<(ostream& os, const master::vector<T>& arr) {
for (int i = 0; i < arr.size(); i++)
os << arr[i] << " ";
return os;
}
ostream& operator<<(ostream& os, const master::vector<int>::iterator& it) {
os << it << " ";
return os;
}
ostream& operator<<(ostream& os, const Point& p) {
os << "p.x = " << p.getX() << " p.y = " << p.getY() << " ";
return os;
}
int main(int argc, char const *argv[])
{
master::vector<int> arr1;
for (int i = 0; i < 22; i++) {
arr1.push_back(i);
cout << "size = " << arr1.size() << " capacity = " << arr1.capacity() << endl;
}
for (auto it = arr1.begin(); it != arr1.end(); it++) {
cout << "iterator for loop -- arr1 " << *it << endl;
}
for (auto it : arr1) {
cout << "arr1 - " << it << endl;
}
return 0;
}
|