這是C++初學者經常遇到的經典問題。簡單來說,模板在編譯階段只是一個「藍圖」,只有當具體類型被實例化時,編譯器才會生成實際的代碼。如果將實現放在.cpp文件中,其他翻譯單元在使用該模板時無法看到實現代碼,導致鏈接器找不到具體實例化的符號,從而報錯。
C++採用分離編譯模型:每個.cpp文件獨立編譯為目標文件,再由鏈接器合併。模板類的成員函數只有在被具體類型(如MyClass<int>)使用時,編譯器才會根據模板生成針對int的代碼。這個過程稱為隱式實例化。
若聲明在.h,實現在.cpp:
template class MyClass<int>;強制生成特定類型代碼,但這限制了模板的通用性,且需預知所有使用類型。#include "MyClass.cpp",本質上仍是將實現暴露給頭文件。模板的「編譯期多態」特性決定了其實現必須可見。將代碼放在頭文件雖然會增加編譯依賴和編譯時間,但這是C++模板機制的固有權衡。現代C++(C++11/17/20)引入了extern template抑制隱式實例化、模塊等特性緩解此問題,但根本原理不變。
參考資源:CSDN博客詳細講解