2009-06-20 42 views
31

我想鏈接到一個模板類的共享庫,但它給我「未定義的符號」錯誤。我將問題簡化爲約20行代碼。C++共享庫模板:未定義的符號錯誤

shared.h

template <class Type> class myclass { 
    Type x; 
public: 
    myclass() { x=0; } 
    void setx(Type y); 
    Type getx(); 
}; 

shared.cpp

#include "shared.h" 
template <class Type> void myclass<Type>::setx(Type y) { x = y; } 
template <class Type> Type myclass<Type>::getx() { return x; } 

的main.cpp

#include <iostream> 
#include "shared.h" 
using namespace std; 

int main(int argc, char *argv[]) { 
    myclass<int> m; 
    cout << m.getx() << endl; 
    m.setx(10); 
    cout << m.getx() << endl; 
    return 0; 
} 

這是我編的lib郭寶宏:

g++ -fPIC -c shared.cpp -o shared.o 
g++ -dynamiclib -Wl,-dylib_install_name -Wl,libshared.dylib -o libshared.dylib shared.o 

和主要程序:

g++ -c main.cpp 
g++ -o main main.o -L. -lshared 

只得到了以下錯誤:

Undefined symbols: 
"myclass<int>::getx()", referenced from: 
    _main in main.o 
    _main in main.o 
"myclass<int>::setx(int)", referenced from: 
    _main in main.o 

如果我刪除了 '模板' 的東西,在shared.h/cpp,並與替換它們只是'int',一切工作正常。另外,如果我只複製&將模板類代碼粘貼到main.cpp中,並且不鏈接到共享庫,則一切正常。

如何,我可以得到一個模板類,像這樣通過一個共享庫的工作?

我使用的MacOS 10.5 GCC 4.0.1。

+0

Duplicate:http://stackoverflow.com/questions/999358/undefined-symbols-linker-error-with-simple-template-class/999383#999383 – 2009-06-20 21:48:21

回答

34

除了其他答案,您可以顯式實例化模板類。這隻有在事先知道模板參數可能呈現的類型時纔有用。您可以使用庫中的所有這些類型實例化模板。

對於你的榜樣編譯,只需添加以下shared.cpp結束:

// Instantiate myclass for the supported template type parameters 
template class myclass<int>; 
template class myclass<long>; 

此實例與類型= INT模板,並將實例化代碼的共享庫。爲您需要的所有類型添加儘可能多的顯式實例。

同樣,如果你希望能夠與任意類型的參數來實例化的模板,然後你必須的定義添加到頭文件,以便在實例化時,編譯器知道模板的源代碼其他編制單位。

16

模板函數定義必須駐留在頭文件中。將來自shared.cpp的定義移至shared.h。

所以,你不能編譯這一個共享庫,然後鏈接到它。它只是不能這樣工作。

+2

因此,使用模板共享庫是不可能的? – nolk 2009-06-20 22:00:35

+2

恰恰相反,這很容易。把它放在一個頭文件中,並分享它。你甚至不需要編譯器;)模板在被實例化之前不會被編譯,所以如果你將一個模板放在一個.cpp文件中,並且將它作爲共享庫編譯,模板代碼就會被簡單地刪除。模板定義必須對用戶可見。 – jalf 2009-06-20 22:23:49

5

您需要在頭文件的模板類的實現也是如此。這是C++中模板的約束。因此,無論從包括主(#包括)shared.cpp或剛剛從shared.cpp移動代碼shared.h

1

編譯器必須看到所有的代碼模板,所以它可以產生的相應的代碼您想要使用的實際類型。 所以你應該把所有的代碼放在你的.h中。文件。

相關問題