模板与泛型 —— using 定义模板别名
2020-05-24 本文已影响0人
从不中二的忧伤
一、类的成员函数模板
二、using 定义模板别名
一、类的成员函数模板
- 普通类和模板类,其成员函数都可以是模板函数,即 “成员函数模板”
- 成员函数模板不允许是虚函数
(1) 普通类的成员函数模板
class Test
{
public:
template<typename T>
void func(T t)
{
cout << t << endl;
}
};
int main()
{
Test test;
test.func("hello world");
return 0;
}
(2) 模板类的成员函数模板
- 模板类的模板,与模板类中的成员函数模板互不打扰
- 模板类的成员函数模板,需要带上模板类的模板,和模板函数的模板
- 模板类的成员函数(普通成员函数/成员函数模板),只有在调用到时才进行实例化(即函数在目标文件 .o 中存在)
template<typename C>
class Test
{
public:
template<typename T>
Test(T v);
private:
C m_tc;
};
template<typename C> // 模板类的模板
template<typename T> // 成员函数模板的模板
Test<C>::Test(T v)
{
cout << "construct v: " << v << endl;
}
int main()
{
// int 类型对应的是 模板类的 typename C
// 2 对应的是构造模板函数中的typename T
Test<int> test(2);
return 0;
}
##### 二、模板显示实例化
1. 为了避免多个.cpp文件实例化相同的类模板的开销,C++11提出 "模板显式实例化":
(1) 实例化定义: 在其中一个 .cpp 文件中,实例化定义,编译器直接实例化出来一个对应的具体的类。
(2) 实例化声明: 在其他的 .cpp文件中,实例化声明,直接使用已经实例化的具体的类。
```
// 实例化定义: 直接实例化出一个 Test<int>
template Test<int>;
// 实例化声明:
extern template Test<int>;
```
二、using 定义模板别名
typedef 用于定义类型的别名:
typedef std::map<int, int> map_i_i;
typedef std::map<int, string> map_i_s;
假设希望定义 std::map<int, 自主指定类型> :
方法一: 定义模板类,在模板类中定义带模板参数的类型成员
template<typename T>
class map_i_t
{
public:
typedef std::map<int, T> type;
};
int main()
{
map_i_t<int>::type map_i_i;
map_i_t<string>::type map_i_s;
return 0;
}
方法二:C++11,可以用using定义模板别名
typelate<typename T>
using map_i_t = std::map<std::string, T>
int main()
{
map_i_t<int> map_i_i;
map_i_t<string> map_i_s;
return 0;
}
- using 在用于定义类型,或者定义类型模板时,包含了 typedef 的所有功能
typedef unsigned int uint_t;
// 相当于使用 using 定义:
using uint_t = unsigned int;
// 定义函数指针:
typedef int(*FuncType)(int, int);
using FuncType = int(*)(int, int);
- 使用using 定义函数指针模板
template<typename T>
using myfunc = int(*)(T, T);
int Add(int a, int b)
{
return a + b;
}
int main()
{
// myfunc<int> 为函数指针类型,是类型名
// pFunc 为函数指针
myfunc<int> pFunc;
pFunc = Add; // 将函数地址赋值给函数指针变量
cout << pFunc(1, 2) << endl;
return 0;
}