1

クラス テンプレートがあり、特殊なインスタンスの動的に割り当てられたインスタンスへのスマート ポインターを使用する場合、クラス テンプレート全体がコンパイラーによって定義されますか、それともメンバー関数がポインターから呼び出されるのを待ちますか?インスタンス化される前ですか?

template <class T>
class Test {
    public:
        void nothing();
        void operation();

        static const int value;
};

template <class T>
const int Test<T>::value = 100;

template <class T>
void Test<T>::nothing() {
   /* invalid code */
   int n = 2.5f;
}

template <class T>
void Test<T>::operation() {
    double x = 2.5 * value;
}

int main() {
    std::unique_ptr<Test<int>> ptr = new Test<int>();  // mark1
    ptr->operation(); // mark2
    return 0;
}
  1. クラス テンプレート全体が mark1 でインスタンス化されますか?

  2. そうでない場合、このコードは正しくコンパイルされ、メンバー関数 Test::nothing() はインスタンス化されないということですか?

4

3 に答える 3

1

クラス テンプレート全体が mark1 でインスタンス化されますか?

はい。クラス テンプレートは暗黙的にインスタンス化されます — クラス テンプレートのみであり、そのすべてのメンバーではありません。

そうでない場合、このコードは正しくコンパイルされ、メンバー関数 Test::nothing() はインスタンス化されないということですか?

notnothing()は、使用されていない場合、インスタンス化されていないことを意味するものではありません。

于 2013-11-06T19:38:38.677 に答える
0

私が使用しているコンパイラ(MS Visual C++)で判明したように、質問で提示されたコードでは、クラステンプレートメンバーのインスタンス化はで行われず、で//mark1行われず、コンパイラによって作成されます。//mark2Test<int>.nothing()

しかし、私が経験していた問題の重要な部分を忘れていたようです。私の実際のクラスは仮想階層の一部であり、MSDN ヘルプ ライブラリによると、すべての仮想メンバーはオブジェクトの作成時にインスタンス化されます。したがって、上記の例では、両方のメンバー関数、つまりoperation()nothing()が仮想の場合//mark2、コンパイラは両方の関数のコードを生成しようとし、 の検証nothing()は失敗します。

http://msdn.microsoft.com/en-us/library/7y5ca42y.aspx

http://wi-fizzle.com/howtos/vc-stl/templates.htm#t9

于 2014-05-13T08:12:29.797 に答える
0

これに対する完全な答えは、おそらく使用しているコンパイラに大きく依存します。

で、コンパイラは、クラス//mark1の少なくとも一部をインスタンス化する必要があることを認識します。Test<int>その時点で実行するか、後のフェーズで実行するかは、コンパイラの設計者次第です。

では//mark2Test<int>.operation()明らかに必要であり、コンパイラの設計者が決定した内容に応じて、後でインスタンス化するか、その場で作成するためにマークされます。

は参照されないためTest<int>.nothing()、コンパイラはそれをインスタンス化するかどうかを自由に選択できます。一部の古いコンパイラは盲目的にクラス全体をインスタンス化しましたが、最新のコンパイラの大部分は、必要であると証明できるもののみをインスタンス化するのではないかと思います (または、少なくとも証明できないものは不要です)。ただし、これがコンパイラ内でどこで発生するかは、コンパイラの設計者がコンパイラを構築した方法によって異なります。

于 2013-11-06T19:53:21.720 に答える