C++模板编译
C++模板编译要编译两次。
以函数模板为例:
第一次编译检查语法
第二次编译生成具体的模板函数
第一次编译发生在正常的编译期间,第二次编译发生在函数模板调用期间。
C++编译机制
C++多文件是独立编译,互不干扰的。
两种编译方式的冲突
main.cpp
#include "Person.cpp"
int main()
{
/*
* 这样写会报错,因为c++的编译机制是文件独立编译
* 当都编译完成之后,链接器去找Print函数的定义的时候
* Person.cpp没有将函数模板进行第二次编译,从而没有生成模板函数
* 导致找不到函数定义而报错
*
* 所以我们一般不把模板进行分离式编译,而是把模板跟主函数放在一起
* 但如果就需要写单独的文件,就改成.hpp,然后包含.hpp
* 这样写表明 那个.h和.cpp文件是一起的
*/
Person<int> a(20, 123);
a.Print();
return 0;
}
Person.cpp
#include "Person.h"
#include <iostream>
using namespace std;
/*
* 模板需要经过两次编译,第一次编译检查语法
* 第二次编译生成具体的模板函数,在调用的时候
* 但是这会和C++的分离编译机制冲突
*/
template<class T>
void Person<T>::Print()
{
cout << this->mAge << " " << this->mId << endl;
}
Person.h
#pragma once
template<class T>
class Person
{
public:
T mId;
T mAge;
public:
Person(T mId, T mAge) :mId(mId), mAge(mAge) {}
void Print();
};
是因为模板只经过一次编译,导致第二次编译无法进行,从而报错找不到函数定义。
解决方法
main文件包含Person.cpp,而不是Person.h
但是这在惯用法上区别工程,可以将Person.cpp文件改为Person.hpp文件,并包含Person.hpp文件,表明这是一个头文件和源文件一起的文件。