[英]Forward declaration of a template function from a seperate file
其他.cpp
#include <iostream>
#include <string>
using std::cout;
template <typename T>
std::ostream & cprint(T &t, std::string msg = "Container", std::ostream & stream = cout){
stream << msg << "\t{ ";
for(typename T::iterator it = t.begin(); it != t.end(); it++)
stream << *it << " ";
stream << "}\n";
return stream;
}
我在一個單獨的文件中有一個模板函數。 我正在嘗試在main.cpp文件中轉發聲明它。
extern template std::ostream & cprint<std::vector<int>>
(T &t, std::string msg = "Container", std::ostream & stream = cout);
我已經嘗試了上面的方法,但它對我不起作用。
編輯:假設 other.cpp 具有如下基本功能,
template <typename T>
void func(T x){
cout << x << endl;
}
如何在 main.cpp 中實例化這個函數?
您應該做的是在標頭中聲明您的模板並擺脫extern
聲明和顯式專業化。
將模板放入.cpp
通常不是很方便,因為它們要求您在同一個.cpp
指定您希望它們適用的所有類型。
但是,另一方面,它提高了編譯速度並且生成的二進制文件有很小的可能性會更小。
我對您的代碼進行了一些更改以使其正常工作。
我也做了一些小的改進。 如果您發現它們令人困惑,請在評論中詢問。
// 1.cpp
#include <iostream>
#include <string>
#include <vector>
template <typename T>
std::ostream &cprint(const T &t, std::string msg = "Container", std::ostream &stream = std::cout)
{
stream << msg << " { ";
for(typename T::const_iterator it = t.cbegin(); it != t.cend(); it++)
stream << *it << " ";
stream << "}\n";
return stream;
}
template std::ostream &cprint(const std::vector<int> &, std::string, std::ostream &);
// 2.cpp
#include <string>
#include <iostream>
#include <vector>
template <typename T> std::ostream &cprint(const T &, std::string = "Container", std::ostream & = std::cout);
int main()
{
std::vector<int> v{1,2,3};
cprint(v);
}
重要部分如下:
顯式實例化。 它必須與模板定義位於同一文件中。
template std::ostream &cprint(const std::vector<int> &, std::string, std::ostream &);
宣言。 它必須位於您要使用模板的文件中。 template <typename T> std::ostream &cprint(const T &, std::string = "Container", std::ostream & = std::cout);
請注意,如果編譯器無法推斷它們,您可以在顯式實例化和 extern 聲明中手動指定模板參數。
用編輯成問題的虛擬模板做同樣的事情留給讀者作為練習。
除了這個,你也應該閱讀: 使用EXTERN模板(C ++ 11)
要使用extern
延遲實例化,您必須完全匹配函數簽名,因此除非T
被定義為std::vector<int>
或其別名 - 與您的模板聲明匹配,否則下面將不起作用。:
extern template std::ostream & cprint<std::vector<int>>
(T &t, std::string msg = "Container", std::ostream & stream = cout);
修理,
extern template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
看這里
更具體地說,
在Header.hpp文件中,我有它的聲明和它的延期:
template <typename T>
std::ostream & cprint(T &t, std::string msg = "Container", std::ostream & stream = cout){
stream << msg << "\t{ ";
for(typename T::iterator it = t.begin(); it != t.end(); it++)
stream << *it << " ";
stream << "}\n";
return stream;
}
//defer instantiation
extern template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
現在,在main.cpp文件中,我有:
int main(){
std::vector<int> v{1, 2, 3, 4, 5};
cprint(v);
}
在Header.cpp文件中,我有它的實例化:
template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
如這里所見
======================
編輯:關於您最近的編輯:
編輯:假設 other.cpp 具有如下基本功能,
template <typename T> void func(T x){ cout << x << endl; }
如何在 main.cpp 中實例化這個函數?
如果翻譯單元main.cpp看到函數模板func
的聲明(來自包含的頭文件,或者您(重新(轉發))在main.cpp 中聲明它,它將編譯為調用函數模板專業化1 ,但鏈接器將無法找到函數模板特化,除非它看到在(另一個)翻譯單元中實例化的函數模板特化的定義。
注意:“函數模板特化”是從函數模板實例化的函數。 見temp.fct/1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.