0

次のようなメイン関数があります。

#include <vector>
#include "mins_ndim.h"
#include "ObjectiveFunction.h"

int main (int argc, char * const argv[]) {

  ObjectiveFunction objective;
  Frprmn<ObjectiveFunction> frprmn(objective);
  std::vector<double> p(2);
  p[0]=7; p[1]=3;
  frprmn.eat();
}

しかし、これは私にエラーを与えます:

Undefined symbols:
  "Frprmn<ObjectiveFunction>::eat()", referenced from:
      _main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

eat()の Frprmn の構造体定義にリストされ、mins_ndim.hで定義されていmins_ndim.cppます。で定義すると、mins_ndim.hこのエラーは発生しません。これはリンクと関係があると思いますが、xcode でそれを整理する方法がわかりません!

4

1 に答える 1

1

クラス テンプレートのメンバー関数の定義は、使用時にコンパイラに表示される必要があります。コンパイラが に遭遇したとき、コンパイラはfrprmn.eat();の実装を認識していないeat(宣言のみを認識したmins_ndim.h) ため、適切なコードを生成できません。

テンプレートは本質的に、適切なテンプレート引数で置き換えられたテンプレート タイプでコンパイラがインスタンス化する必要があるコードの一部であることを思い出してください。コンパイラは、テンプレート引数としてeat生成できるように、 の実装を認識できる必要があります。ObjectiveFunction

このため、関数テンプレートまたはクラス テンプレートのメンバー関数をヘッダー ファイルに実装するのが一般的です。

別の方法として、クラス テンプレートの定義とその実装を分けておきたい場合は、実装ファイルをヘッダー ファイルの最後に含めることもできます。これは、典型的な組み込み方法を逆にします。これを明確にするために、実装ファイルの名前に.tpp拡張子 (tテンプレート) を付けるのが一般的です。これにより、どのファイルにどのファイルが含まれているかがより明確になります。

于 2013-04-09T17:17:53.187 に答える