0

我的應用程序存在一個普遍問題。 我想使用一個Array類的惰性初始化,以提高性能;當所有的代碼都在一個單獨的* .h文件中時,所有工作都正常,但是當我將代碼分割成* .h * .cpp文件時,編譯器返回一個鏈接器錯誤。 在頭文件中我有一個延遲初始化和模板 - 鏈接器錯誤

template <class T> 
class simpleArray { ... some methods\operators declarations. ... } 

template <typename T, typename derType=simpleArray<T>> 
class myArray{.... some methods\operators declarations. ... } 

,我已經的顯式聲明:

template class myArray<double>; 
template class myArray<int>; 
template class simpleArray<double>; 
template class simpleArray<int>; 

在* .cpp文件我已經實施的方法和運營商。 特別是我有兩個任務操作員:

template <class T, class derType> 
myArray<T,derType>& myArray<T,derType>::operator= (myArray<T,derType> const& right) 
    {... some code ...} 

template<class T, class derType> 
template <class T2, class R2> 
    myArray<T,derType>& myArray<T,derType>::operator= (myArray<T2,R2> const& right) 
    { ... some code ...} 

第一個工作正常,第二個(ARRA =陣列)返回以下錯誤:

Error 70 error LNK1120: 1 unresolved externals 
Error 69 error LNK2019: unresolved external symbol "public: class myArray <double,class simpleArray<double> > & __thiscall myArray <double,class simpleArray<double> >::operator=<int,class simpleArray<int> >(class myArray <int,class simpleArray<int> > const &)" 

可以請你提出一些解決方案?我是否必須將所有代碼包含在同一個文件中? 我希望已經清楚。謝謝你的支持!

詩篇。在使用模板時,是否有一些關於代碼組織的「最佳實踐」文檔?

回答

1

的問題提出了,因爲你已經放置模板operator=定義.cpp文件:

template <class T, class derType> 
template <class T2, class R2> 
myArray<T,derType>& myArray<T,derType>::operator=(myArray<T2,R2> const& right) 
{ ... } 

顯式實例正在使用罰款模板類的普通函數成員的作品,但它不與模板函數模板類的成員。 僅僅因爲在明確的安裝指令中,您只提供了作爲類模板參數的實際類型TderType類型,但不提供作爲函數模板參數的T2R2

可能的解決方案:

  1. 移動模板operator=定義.h,所以編譯器將能夠在通話的地方初始化它
  2. 提供明確的實例化模板operator=T/derType所有可能的組合和T2/R2

樣本:

// Explicit instantiation of template classes 
template class myArray<double>; 
template class myArray<int>; 
template class simpleArray<double>; 
template class simpleArray<int>; 

// Explicit instantiation of template members 
template myArray<double>& myArray<double>::operator=(myArray<int> const&); 
template myArray<int>& myArray<int>::operator=(myArray<double> const&); 

P.S. David Vandevoorde和Nicolai M. Josuttis的最佳模板指南仍然是C++ Templates. The Complete Guide。它並沒有涵蓋新的C++ 11功能,但基礎知識和最先進的主題仍然是實際的。

+0

謝謝你的回答:這很清楚!我希望有一種不同的方式,因爲我使用表達式模板來實例化所有運算符的組合。對?我將把所有文件放在一個* .h文件中。 – Dersu

+0

另一個問題:如果我想將所有代碼導出爲靜態庫(a * .h和a *)。lib文件)如何導出模板和表達式模板?我是否必須導出所有* .h文件?所以用戶將知道代碼和實現...或者我可以創建另一個* .h文件,與第一個相關,只有聲明?謝謝! – Dersu

+0

@Dersu是的。除了導出完整的定義外,沒有辦法導出模板。所以你必須導出所有的標題,對。或者不是導出模板本身,而是隻導出一些明確的安裝。對於表達式模板,由於必須實例化所有組合並限制模板化表達式中的操作次數,因此它看起來不太可能。 – Rost