2011-12-27 77 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