1. ホーム
  2. c++

[解決済み] テンプレートクラスの前方宣言時に「未定義のテンプレートの暗黙のインスタンス化」が発生する。

2022-01-28 06:26:38

質問

私はテンプレートクラスを前方宣言する必要があるいくつかのコードを持っています(または、少なくとも、前方宣言は私にとって物事をはるかに容易にする...)。私が抱えている問題の簡易版を書きましたので、ここに表示することができます。

template<bool>
class MyTemplateClass;

int main( int argc, char* argv[] )
{
    MyTemplateClass<false> myTemp;  // error here
    myTemp.GetTheValue();
    return 0;
}

template<bool bShouldMult>
class MyTemplateClass
{
    int m_myint;
    float m_myfloat;

public:
    MyTemplateClass() : m_myint(5), m_myfloat(3.0f) {}
    float GetTheValue()
    {
        return m_myint * (bShouldMult ? m_myfloat : 1.0f);
    }   

};

コメントされた行で出ているエラーは

Error - implicit instantiation of undefined template 'MyTemplateClass<false>'

MyTemplateClassの前方宣言には、他にどのような詳細を含める必要があるのでしょうか?エラーは次の行から来ないので、私はそれがメソッドが未定義であるという事実のためではないと仮定しています。使用しているコンパイラはLLVM/CLangで、Macでコンパイルしています。

どのように解決するのですか?

テンプレートであろうとなかろうと、任意の型の変数を宣言するためには、その型の定義全体が利用可能でなければなりません。テンプレートを前方に宣言して、あたかもそれが定義されているかのように使い始めることはできません。その時点でできることは、テンプレートに基づく型のオブジェクトへのポインタを、このように宣言することだけです。

MyTemplateClass<false> *myTempPtr;  // No error here

残念ながら(予想通りではありますが)、これでエラーは次の行に移動しました。このポインタの初期化という問題は残っています。 new MyTemplateClass<false> というエラーが表示されます。

テンプレートの定義を使用する場所より先に移動するように、コードを整理し直す必要があります。コンパイラは、テンプレートのインスタンス化とそのメソッドの呼び出しを開始する時点で、定義全体を把握する必要があるのです。