3

Microsoft には、テンプレートのインスタンス化が外部になることを宣言できる拡張機能があります。したがって、暗黙的にインスタンス化されることはありません。少なくともそれが理論です。それをコードで再現してみました

#include <vector>

class Foo{
    int i;
public:
    virtual ~Foo();
};

extern template class std::vector<Foo>;

これは私に与えます

warning C4231: nonstandard extension used : 'extern' before template 
explicit instantiation

ただし、他には何も起こらないようです。push_back を使用しているにもかかわらず、プログラムは find のリンクを続行します (そして、push_back がインスタンス化されたことを dumpbin が示しています)。

宣言したときだけ

extern template void std::vector<Foo>::push_back(const Foo&);

予想どおりリンカー エラーが発生します。

では、インスタンス化全体 (すべてのメンバー) を明示的に宣言して、暗黙的なインスタンス化を防ぐにはどうすればよいでしょうか?

4

1 に答える 1

6

拡張機能のドキュメントにある次のメモに悩まされていると思います。

特殊化の extern キーワードは、クラスの本体の外部で定義されたメンバー関数にのみ適用されます。クラス宣言内で定義された関数はインライン関数と見なされ、常にインスタンス化されます。

vector::push_back()(および std::vector<> テンプレートのほとんどまたはすべて) は、クラス宣言内で定義されます。

メモに書かれていることを考えるとextern、メンバー関数の on はインスタンス化されるはずですが、この拡張機能が十分に文書化されていない、または十分に指定されていないことは驚くことではありません。

extern各メンバー関数で 明示的に実行しないと、やりたいことができないと思います。

于 2010-11-23T19:29:43.917 に答える