美文网首页
第二章:模板类

第二章:模板类

作者: 找不到工作 | 来源:发表于2020-12-26 13:46 被阅读0次

与函数类似,类也可以使用模板参数。典型例子就是cpp标准库里的各种容器。

Takeaways:

  • 模板类的成员函数只在被使用到时才实例化

2.1 例子:栈

#include <vector>


template<typename T>
class Stack {

private:
  std::vector<T> elems_;

public:
  void push(const T& elem);
  void pop();
  T const& top() const;
  bool empty() const {return elems_.empty();}
};


template<typename T>
void Stack<T>::push(const T& elem) {
  // append copy of passed elem
  elems_.push_back(elem);
}

template<typename T>
void Stack<T>::pop() {
  assert(!elems_.empty());
  elems_.pop_back();
}

template<typename T>
T const& Stack<T>::top() const {
  assert(!elems_.empty());
  return elems_.back();
}

没什么特别需要注意的,下面的代码是如何使用:

#include "stack1.hpp"

#include <string>
#include <iostream>

int main(int argc, char const *argv[]) {
  Stack<int> intStack;
  Stack<std::string> stringStack;

  intStack.push(7);
  std::cout<<intStack.top()<<std::endl;

  stringStack.push("hello");
  std::cout<<stringStack.top()<<std::endl;
  stringStack.pop();
  return 0;
}

对于模板类,成员函数只在被使用到时才实例化。如上代码中,pop()只对stringStack实例化了,因为它并未被intStack调用。

2.3 模板类的部分使用

由于成员函数只有被调用才会实例化,我们不需要保证每个成员函数都对某个类型可用。

例如,我们可以给 stack 添加一个 str() 方法来返回自身的字符串。

template<typename T>
std::string Stack<T>::str() const {
  std::stringstream ss;

  ss << '[';
  for (int i=0; i<elems_.size(); i++) {
    ss << elems_[i];
    if (i!=elems_.size()-1) {
      ss << ',';
    }
  }
  ss << ']';

  return ss.str();
}

不支持 << 操作符的类型同样可以使用这个模板类。

  Stack< std::pair<int, int> > pairStack;
  pairStack.push({4, 5});
  pairStack.push({6, 7});
  pairStack.pop();
  std::cout<<pairStack.top().first<<std::endl; // output 4
  std::cout<<pairStack.top().second<<std::endl; // output 5

但是如果尝试使用 str() 函数就会报错:

std::cout<<pairStack.str()<<std::endl; // compile error

2.4 友元

略,与模板关系不大

2.5 模板类的特化

类似于模板函数的重载,我们可以给出指定模板类的某些模板参数进行特化。特化可以使我们为某个模板实例单独实现一套逻辑。

为了特化模板类,我们必须用 template<>,并使用具体的类替换 T。如下就是对 std::string 的特化:

template<>
class Stack<std::string> {
  ...
};

类似的,我们也需要把成员函数中所有的 T 换为 std::string

2.6 部分特化

我们也可以使模板类“部分”特化来处理一类的类型。例如,对指针类型:

template<typename T>
class Stack<T*> {
  ...
};

注意,这里我们仍然保留了 template<typename T>, 但是对指针进行了特化:class Stack<T*>

多参数的部分特化

对于多个模板参数的模板类,例如:

template<typename T1, typename T2>
class MyClass {
  ...
};

我们可以进行多种特化:

// partial specialization: both template parameters have same type
template<typename T>
class MyClass<T, T> {
  ...
};

// partial specialization: second type is int
template<typename T>
class MyClass<T, int> {
  ...
};

// partial specialization: both parameters are pointers
template<typename T1, typename T2>
class MyClass<T1*, T2*> {
  ...
};

对于不同的调用,会匹配不同的特化:

MyClass<int, float> mif;  // uses MyClass<T1, T2>
MyClass<float, float> mff;  // uses MyClass<T, T>
MyClass<float, int> mfi;  // uses MyClass<T, int>
MyClass<int*, float*> mpp;  // uses MyClass<T1*, T2*>

但是如果某种类型可以匹配多种特化,则会报错:

MyClass<int, int> mii; // ERROR, matches <T, T> and <T, int>
MyClass<int*, int*> mpp; // ERROR, matches <T, T> and <T1*, T2*>

遇到这种情况,需要添加更佳匹配的特化,例如:

// partial specialization: both parameters are pointers
template<typename T>
class MyClass<T*, T*> {
  ...
};

2.7 默认模板参数

2.8 类型别名

using 的用法,略

2.9 模板参数类型推断

C++17 新引入的功能:

Stack<int> intStack1;
Stack<int> intStack2 = intStack1; // OK in all versions
Stack intStack3 = intStack1; // OK since C++17

语法糖,略。

相关文章

  • ★07.关于类模板

    简述 类模板:是类类型的模板,如:vector。 模板类:类模板的实例化,如:vector 。 类模板的模板参数无...

  • 第二章:模板类

    与函数类似,类也可以使用模板参数。典型例子就是cpp标准库里的各种容器。 Takeaways: 模板类的成员函数只...

  • 14/12

    成员模板:模板类中成员变量是模板类对象(1),模板类中函数是模板函数(2)

  • JAVA 第二章 —— 类

    第二章 1.类的定义与实例化 1.1类的定义 类必须先定义才能使用,类是创建对象的模板,创建对象也叫类的实例化。语...

  • 14/15

    约束模板友元 模板类的外边定义一个模板函数,在模板类中将模板函数具体化为模板类的友元函数 非约束模板友元 模板类中...

  • 读书笔记:《学会写作》-模板写作、新媒体写作

    继续《学会写作》的阅读。 “模板写作”第一节作者给出了四类实用的模板:通知类模板、分析类模板、计划类模板和总结类模...

  • 模板方法模式

    模板抽象类 模板抽象类实现类 使用

  • 模板与泛型 —— using 定义模板别名

    一、类的成员函数模板 二、using 定义模板别名 一、类的成员函数模板 普通类和模板类,其成员函数都可以是模板函...

  • 10-C++远征之模板篇-学习笔记

    C++远征之模板篇 将会学到的内容: 模板函数 & 模板类 -> 标准模板类 友元函数 & 友元类 静态数据成员 ...

  • 慕课网-C++远征之模板篇(上)-学习笔记

    C++远征之模板篇 将会学到的内容: 模板函数 & 模板类 -> 标准模板类 友元函数 & 友元类 静态数据成员 ...

网友评论

      本文标题:第二章:模板类

      本文链接:https://www.haomeiwen.com/subject/chodnktx.html