这一系列笔记来自对Cherno的油管视频学习的一个记录,他是EA的游戏引擎工程师,制作了一系列关于C++,openGL,游戏引擎制作等的视频。
模板,让编译器按照你设定的规则去编译,这是一个非常庞大的话题。
1、我们从一个简单的例子上开始入手
void Print(int value) { std::cout << value << std::endl; } void Print(float value) { std::cout << value << std::endl; } void Print(std::string value) { std::cout << value << std::endl; }
我们希望能够不需要手动去设定所有的类型,而能去填充,这个时候就需要模板Templates。
#include <iostream> #include <string> template<typename T> void Print(T value) { std::cout << value << std::endl; } int main() { Print(5); Print("Hello"); Print(5.5f); std::cin.get(); }
这是一个模板,它将在编译的时候被评估,这不是一个真正的函数,只有当我们调用它,并且基于什么类型去调用它的时候,才会被当做真正的source code,创建成函数并且编译。
- 这意味着,如果我们不去调用它(比如main函数里空无一物),这个print function就只是一个模板为了证明这一点,我们可以故意写错,比如在cout<< valu,即使是错误的变量,也能通过编译,总之,如果不调用,函数就不存在。
template<typename T>
typename作为模板参数的类型,T只是一个名字,我们可以写成任何我们想要的名字,我们可以在整个过程中使用它。
我们也可以实际上去指定T是什么(这里指的是类型),不过在这个例子里面没必要。
Print<int>(5);
2、接下来我们换另一个例子
template <int N> class Array { private: int m_Array[N]; public: int GetSize() const { return N; } }; int main() { Array<5> array; std::cout << array.GetSize() << std::endl; std::cin.get(); }
在这里例子里,可以看到我们不仅仅是使用types,甚至可以使用整数或者其他数据类型,去指定我们怎么样生成这个类。
3、换另一个例子,更加进一步
#include <iostream> #include <string> template <typename T,int N> class Array { private: T m_Array[N]; public: int GetSize() const { return N; } }; int main() { Array<std::string,50> array; std::cout << array.GetSize() << std::endl; std::cin.get(); }
以上都是模板一些简单的应用,模板的运用可以变得非常crazy,但是Cherno觉得,一旦你使用过度,不得不坐下来花上三个小时去弄清楚到底执行了什么代码,对于模板的应用就国有了,我们完全可以手动完成一些事情,自己编写代码而不是去创建这种庞大的template magic。同样他提到使用模板的地方,比如日志系统之类的东西,或者是材质系统之类,总之那是会应用的。