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 に答える