0

さまざまなコンテキストで外部関数を呼び出す必要があるクラスがあります。私は物事を柔軟に保ちたいので、ファンクター、関数ポインターなどで動作するインターフェイス (Numerical Recipes の第 3 版に触発された) を使用しています。単純化された例は次のようになります。

class MyClass {
  public:
    template <class T>
    MyClass(T &f_) { f = f_; }
  private:
    int (*f)(int);
};

int myFn(int i) {
  return i % 100;
}

int main() {
  MyClass test(myFn);
  return 0;
}

ここまでは順調ですね; g++ はこれを問題なくコンパイルします。私の実際のアプリケーションでは、さらに多くのコードがあるため、複数のファイルに分割されています。例えば、

test2.h:

#ifndef __test2__
#define __test2__

class MyClass {
  public:
    template <class T>
    MyClass(T &f_);    
 private:
    int (*f)(int);
};

#endif

test2.cpp:

#include "test2.h"

template <class T>
MyClass::MyClass(T &f_) {
  f = f_;
}

main.cpp:

#include "test2.h"

int myFn(int i) {
  return i % 100;
}

int main() {
  MyClass test(myFn);
  return 0;
}

を使用してこれをコンパイルしようとするとg++ test2.cpp main.cpp、次のリンク エラーが発生します。

/tmp/ccX02soo.o: In function 'main':
main.cpp:(.text+0x43): undefined reference to `MyClass::MyClass<int ()(int)>(int (&)(int))'
collect2: ld returned 1 exit status

g++ は、test2.cpp もコンパイルしようとしているという事実を認識していないようです。ここで何が起こっているのかについてのアイデアはありますか?

ありがとう、

--クレイグ

4

1 に答える 1

1

テンプレートクラスは、完全に特殊化されていない限り、それらを使用するすべての翻訳ユニットに実装が表示される必要があります。

つまり、ヘッダー内の実装を移動する必要があります。

//test2.h
#ifndef __test2__
#define __test2__

class MyClass {
  public:
    template <class T>
    MyClass(T &f_);    
 private:
    int (*f)(int);
};

template <class T>
MyClass::MyClass(T &f_) {
  f = f_;
}

#endif
于 2012-04-11T09:18:38.767 に答える