2

重複の可能性:
C ++テンプレート、リンクエラー

2つのリンクエラーがあり、コードの何が問題になっているのか、どのように修正するのかわかりません。

main.obj:-1:エラー:LNK2019:未解決の外部シンボル "public:__thiscall A :: A(void)"(?? 0?$ A @ VB @@@@ QAE @ XZ)関数 "public:__thiscallで参照B :: B(void) "(?? 0B @@ QAE @ XZ)

main.obj:-1:エラー:LNK2019:未解決の外部シンボル "public:void __thiscall A :: exec(void(__thiscall B :: *)(void))"(?exec @?$ A @ VB @@@@ QAEXP8B @@ AEXXZ @ Z)関数 "public:void __thiscall B :: run(void)"(?run @ B @@ QAEXXZ)で参照されます

コードを少し説明する:このクラスは、派生クラスから関数を実行する必要があります。関数execは、派生クラスパラメーターの関数を使用して派生クラスから呼び出されます。この関数の署名はvoid function();

//header.h

#ifndef HEADER_H
#define HEADER_H

template <class T>
class A
{
public:
    typedef void (T::*ExtFunc)();

    A();
    void funcA();
    void exec(ExtFunc func);
};

#endif // HEADER_H

//header.cpp

#include "header.h"

template<typename T>
A<T>::A() { }

template<typename T>
void A<T>::funcA()
{
    cout << "testA\n";
}

template<typename T>
void A<T>::exec(ExtFunc func)
{
    (T().*func)();
}

私はmain.cppAクラスからクラスを派生させ、派生したクラスをテンプレートパラメータとして渡します。次に、関数execを介してrun()関数を実行します。//main.cpp

#include <iostream>
#include "header.h"
using namespace std;

class B : public A<B>
{
public:
    B() { }

    void run()
    {
        exec(&B::funcB);
    }

    void funcB()
    {
        cout << "testB\n";
    }
};

int main()
{
    B ob;
    ob.run();

    return 0;
}

誰かが何が起こっているのか教えてもらえますか?...

4

1 に答える 1

2

テンプレートを使用している場合、通常、実装を.cppファイルに入れることはできません。クラス全体をヘッダーに入れる必要があります。したがって、すべてのコードをheader.cppから.hに移動します。

これを回避するには、.cppファイル内で明示的なインスタンス化を実行します。特定のタイプのテンプレートをインスタンス化します。ただし、これには、インスタンス化が必要なタイプを事前に知っておく必要があり、新しいインスタンス化を追加できなくなります。唯一の利点は、コンパイル時間の短縮です。

于 2012-09-03T07:10:11.327 に答える