2016-01-09 33 views
0

我已經爲一個非常簡單的打印函數編寫了一個模板,並且將它放在了一個所有處理控制檯IO的自定義函數庫中。在單獨的.cpp文件中專門設計函數模板

我已經爲一個特定的項目編寫了第二個庫,那是一個原創的小孩。它專門化了其中一個模板。

我遇到了一個錯誤(我懷疑)是由main.cpp中的調用在專用模板聲明之前發生的。錯誤有這樣一行:

In instantiation of 'static void baseIO::print(S) [with s = std::vector<int>]' 

這意味着它的調用的specialIO::print()baseIO::print()代替

我試圖使specialIO::print()普通函數,而不是一個模板,並在頭宣佈它作爲正常的,但否認主.cpp訪問基本模板。

有沒有辦法讓我的專業化在main.cpp中可用而無需 宣佈 在那裏實現呢?

//in main.cpp 
#include <vector> 
#include "specialIO.h" 

main(){ 
    std::vector<int> myVector; 
    specialIO::print(myVector); 
    specialIO::print("hello world"); 
    return 1; 
} 

//in baseIO_templates.cpp - templates are outside of the baseIO.cpp file because of linker errors 
template<typename S>  //primary template 
void baseIO::print(S str){ 
    std::cout << str; 
} 

//baseIO.h 
class baseIO{ 
public: 
    template<typename S> //primary template 
    static void print(S str); 
} 
#include "baseIO_templates.cpp" 

//specialIO.cpp 
template<>    //specialized template 
void static specialIO::print(vector<int> myVector){ 
    for(int i : myVector){ 
     baseIO::print(i) 
    } 
} 

//specialIO.h 
class uberIO : public baseIO { 
    //empty 
} 
+0

任何特定的原因,爲什麼你總是複製矢量,而不是通過const ref傳遞它? – axalis

回答

0

調用代碼時,編譯器必須提供所有的模板代碼。因此,如果您聲明瞭template<T> void SomeFunction(T x); - 那麼當您使用std::stringfloatMyStruct調用它時,編譯器需要知道SomeFunction的定義。因爲如果直到現在還不知道類型,編譯器才能找出如何找到正確的實現(或爲正確實現生成代碼)......

因此,您不能將模板實例的.cpp文件 - 這是可能把專業化.cpp文件,如果你在一個頭文件聲明它們,所以:

class specialIO : public baseIO { 
public: 
    template<>void static print<std::vector>(std::vector<int> v); 
}; 

但如果你把它空,編譯器將不即使知道有這樣的打印功能,所以不能調用它 - 它會嘗試將std::vector傳遞到常規baseIO::print<T>,這將不起作用,因爲它不能這樣做。

+0

我懷疑我需要在標題中包含某些內容,但不知道是什麼。愛你的解釋的徹底性。謝謝! – ISaidWutWut

+0

添加到我的代碼,但現在我得到「錯誤:在非名稱空間範圍'顯式專業化'class specialIO' – ISaidWutWut