2011-12-27 67 views
2

我創建了一個函數模板,讓我得到的數據用於任何數據類型,但我在編譯收到錯誤消息:功能模板鏈接錯誤

Undefined symbols for architecture i386: 
    "bool Json::getData<double>(double, Json&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, DataType)", referenced from: 
     Coupon::initCoupon(int const&, Json&)in libkuapay.a(Coupon.o) 
ld: symbol(s) not found for architecture i386 
collect2: ld returned 1 exit status 
scons: *** [kuaposgw] Error 1 
scons: building terminated because of errors. 

該函數聲明爲:

template < class T> static bool getData(T data, Json &jsonObject, const string &key, DataType dataType); 

,並呼籲爲:

Json::getData (couponList[cpnCnt].discount, couponReader, "discount", realType); 

其中couponList[cpnCnt].discount是雙。

代碼本身在我的「內部」目錄中編譯得很好,但是我在 「外部」目錄中得到了上述錯誤信息,其中後者基本上是內部代碼的包裝。

+0

您可以包括函數的定義?錯誤表明它有問題。 – kichik 2011-12-27 18:43:19

+1

'ld'是鏈接器,不是編譯器。所以當它抱怨這意味着你有一個鏈接器錯誤,而不是編譯器錯誤。 – Omnifarious 2011-12-27 18:50:34

回答

2

模板的當前狀態通常要求您在那裏有函數聲明的地方有函數聲明。

模板工作方式,編譯器基本上爲模板參數上的每個變體制作一個自定義版本的函數。由於編譯器無法預先知道所有這些不同的模板參數將會是什麼(它會是int還是double或某個其他文件中聲明的未知類型?),直到函數被調用時才能創建這些版本。

這意味着當您調用該函數時,整個函數定義必須可供編譯器使用。爲了做到這一點,你應該把函數定義放在一個頭文件中。

還有其他方法可以做到這一點。類模板的顯式實例化。聲明一個函數沒有模板參數的重載。但總的來說,您的整個模板定義必須位於頭文件中。

+0

嗨,謝謝你的迴應,我會嘗試添加函數定義到標題。與此同時,這裏的定義是: – jdeckman 2011-12-27 19:01:14

+0

模板布爾的Json ::的getData(T數據,JSON和的JSONObject,常量字符串和鍵,數據類型的dataType) { 如果(!jsonObject.hasKey(鍵)) 返回false; if(jsonObject.value(key)== json_spirit :: null_type) return false; 如果(的dataType ==的RealType) { 如果(jsonObject.value(鍵).TYPE()== json_spirit :: str_type) 數據= NumberParser :: parseFloat(jsonObject.value(鍵).get_str()) ; else data = jsonObject.value(key)。get_real(); } 還真 } – jdeckman 2011-12-27 19:08:20

+0

@ user1118089:嗯,這看起來不錯,但它會更好,如果你用定義來更新你的問題,並說這是在哪個文件 – Omnifarious 2011-12-27 22:35:18

0

模板沒有在C++中自動實例化,而是在隱式使用或明確使用時實例化。當使用模板時(例如,通過將其放入頭文件中)模板實例化可用時,可以使用該函數來觸發前一種情況,如所描述的@Omnifarious。

作爲替代方案,可以使功能非static,明確在源文件中實例化它:

template bool getData<double>(double data, Json &jsonObject, const string &key, DataType dataType); 
+0

非常感謝! – jdeckman 2011-12-28 01:14:36