5 模板别名和模板参数

模板别名

在C++11中提供了模板别名。使用它可以方便的对一些具有不同类型参数的模板命名。例如有Matrix类模板:

template <typename T, int Line, int Col>
class Matrix{
    ....
};

为了可读性,我们增加2个特殊的矩阵:SquareVector,分别表示行列相同的方阵和一维的向量。可以使用关键字using声明类型别名:

template <typename T, int Line>
using Square = Matrix<T, Line, Line>; // (1)

template <typename T, int Line>
using Vector = Matrix<T, Line, 1>;    // (2)

模板别名能为部分绑定的模板创建直观的名称,SquareVector用起来十分方便且符合直觉。

Matrix<int, 5, 3> ma;
Square<double, 4> sq;
Vector<char, 5> vec;

模板别名还有一个典型的应用是Type-Traits库。

当使用std::move(arg)时,编译器会使用std::remove_reference来消除引用:

static_cast<std::remove_reference<decltype(arg)>::type&&>(arg);   // (1)

static_cast<std::remove_reference_t<decltype(arg)>&&>(arg);       // (2)

其中(2)使用模板别名:

template< class T >
using remove_reference_t = typename remove_reference<T>::type;

模板参数

模板参数可以是类型,非类型和模板。

类型

类型是最常用到的模板参数,例如:

std::vector<int> myVec;
std::map<std::string, int> myMap;
std::lock_guard<std::mutex> myLockGuard;

非类型

非类型可能如下:

  • 左值引用
  • nullptr
  • 指针
  • 枚举
  • 整数值

整数值是最为常用的。例如std::array需要在编译时期指定其大小。

std::array<int, 3> myArray{1, 2, 3};

模板

模板也能作为模板的参数。

#include <iostream>
#include <list>
#include <vector>
#include <string>

template <typename T, template <typename, typename> class Cont >    // (1)
class Matrix{
public:
  explicit Matrix(std::initializer_list<T> inList): data(inList) {  // (2)
    for (auto d: data) std::cout << d << " ";
  }
  int getSize() const{
    return data.size();
  }

private:
  Cont<T, std::allocator<T>> data;                                  // (3)                               

};

int main(){

  std::cout << '\n';

  Matrix<int, std::vector> myIntVec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // (4)
  std::cout << '\n';
  std::cout << "myIntVec.getSize(): " << myIntVec.getSize() << '\n';

  std::cout << std::endl;

  Matrix<double, std::vector> myDoubleVec{1.1, 2.2, 3.3, 4.4, 5.5}; // (5)
  std::cout << '\n';
  std::cout << "myDoubleVec.getSize(): "  << myDoubleVec.getSize() << '\n';

  std::cout << '\n';
                                                                    // (6)
  Matrix<std::string, std::list> myStringList{"one", "two", "three", "four"};  
  std::cout << '\n';
  std::cout << "myStringList.getSize(): " << myStringList.getSize() << '\n';

  std::cout << '\n';

}

Matrix有2个模板参数,第一个参数是元素的类型,第二个代表容器。其中第二个模板参数还是一个模板,它需要2个模板参数:第一个模板参数是容器中元素的类型,第二个参数是容器的空间分配器。

在Matrix中可以使用container< type of the elements, allocator of the elements>形式的容器,例如:std::vector, std::deque, std::list。std::array 和 std::forward_list是不可用的,因为std::array需要一个整数值来指定其大小,而std::forward_list不支持size方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值