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是双。

代码本身在我的“内部”目录中编译得很好,但我在“外部”目录中收到上面的错误消息,后者本质上是内部代码的包装器。

4

2 回答 2

2

模板的当前状态通常要求您在有函数声明的地方有函数定义。

模板的工作方式,编译器基本上为模板参数的每个变体制造一个自定义版本的函数。由于编译器无法提前知道所有这些不同的模板参数将是什么(它是在其他文件中声明的类型int还是double未知类型?)它在调用函数之前无法创建这些版本。

这意味着当您调用函数时,编译器必须可以使用整个函数定义。为了实现这一点,您应该将函数定义放在标题中。

还有其他方法可以做到这一点。类模板的显式实例化。函数没有模板参数的重载声明。但一般来说,您的整个模板定义必须在头文件中。

于 2011-12-27T18:44:19.403 回答
1

模板不会在 C++ 中自动实例化,而是在隐式使用或显式实例化时。当使用模板时模板实例化可用时,您可以使用该函数触发前一种情况(例如,通过将其放入头文件中),如@Omnifarious 所述。

作为替代方案,您可以使函数static在源文件中非显式地实例化它:

template bool getData<double>(double data, Json &jsonObject, const string &key, DataType dataType);
于 2011-12-27T19:54:29.943 回答