問題タブ [explicit-instantiation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
614 参照

c++11 - C++11 extern テンプレート: 実際に必要な場所は?

C++03 には、テンプレート クラスのインスタンス化を強制するテンプレートの明示的なインスタンス化定義( ) があります。template class Foo<int>

C++11 では、テンプレート クラスの暗黙的なインスタンス化を防ぐテンプレートの明示的なインスタンス化宣言( ) があります。extern template class Foo<int>(クラス テンプレートのインスタンス化)

コンパイル時間を短縮するために明示的なインスタンス化宣言が実際に必要な状況をシミュレートしようとしています。しかし、私はできません。この機能がなくてもすべてが機能するように見えます (または機能しません)。

次に例を示します。

結果は、( ) 行をコメントするかどうかに依存しません。extern template class Foo<int>;

両方の *.obj ファイルのシンボルを次に示します。

ダンプビン /SYMBOLS test1.obj

011 00000000 UNDEF notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))'

012 00000000 UNDEF notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

013 00000000 SECT4 notype () 外部 | ?baz@@YAXXZ (void __cdecl baz(void))

...

ダンプビン /SYMBOLS Foo.obj

017 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

018 00000000 SECT6 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

test1.obj でUNDEFFoo<int>::Foo<int>(int)int Foo<int>::get(void)constマークされていることに注意してください。これは、別の場所で解決する必要があることを意味します (つまり、Foo は 1 回だけコンパイルされました)。

試み #2:

Foo.h ファイルで完全なテンプレートを定義した場合 (明示的なインスタンス化定義なしextern template)、役に立ちません。テンプレートは 2 回 (test1.cpp と test2.cpp の両方で) コンパイルされます。

例:

シンボル ダンプは次のとおりです。

ダンプビン /SYMBOLS test2.obj

01D 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

01E 00000000 SECT8 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

01F 00000000 SECT6 notype () 外部 | ?bar@@YAXXZ (void __cdecl bar(void))

ダンプビン /SYMBOLS test1.obj

01D 00000000 SECT6 notype () 外部 | ?baz@@YAXXZ (void __cdecl baz(void))

01E 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

01F 00000000 SECT8 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

両方の *.obj ファイルで Foo が提示します。

だから私の質問は、明示的なインスタンス化宣言の有用性は何ですか? それとも、テストで何かを見逃しているのでしょうか?

私はVS2013コンパイラを使用しています。

0 投票する
0 に答える
1035 参照

c++ - C++ テンプレートの明示的なインスタンス化宣言: ベスト プラクティス

私の質問は、テンプレートの明示的なインスタンス化宣言を正しい方法で使用するにはどうすればよいですか?

テンプレート クラス があるとしtemplate<class T> Fooます。

この機能に対処する方法は次のとおりです。

テンプレートの宣言をFoo.hファイルに入れ、実装をファイルに入れFoo.inl、これFoo.inlをファイルの最後に含め、. また、たとえばファイルで明示的なテンプレートのインスタンス化定義を使用する必要があります (もちろん、この cpp ファイルにも含める必要があります)。Foo.hextern template class Foo<int>;#include "Foo.inl"Foo.cppFoo.h

これらすべてを行うと、エラーが発生します。明示的なテンプレートのインスタンス化宣言の直後に明示的なテンプレートのインスタンス化定義を使用することはできません。わかりました、テンプレート宣言とを別のファイルに入れて、に含めましょう。最終的に次のようになりました。#include "Foo.inl"Foo.hppFoo.cpp

Foo.hpp

Foo.inl

フー。

Foo.cpp

そして、このテンプレートを次のように使用します。

test1.cpp

Fooが多すぎませんか?これにどのように対処しますか?

私の英語でごめんなさい。

アップデート:

問題は、明示的なテンプレートのインスタンス化の定義やテンプレート コード自体の構成方法に関するものではなく、明示的なテンプレートのインスタンス化宣言の使用法と、それを使用しようとすると生成される「ファイル地獄」に関するものです。

0 投票する
1 に答える
330 参照

c++ - 可変引数コンストラクターの明示的なインスタンス化: template-id がどのテンプレート宣言とも一致しません

可変引数コンストラクターを明示的にインスタンス化しようとしています。すべての引数を出力するこの最小限の例では、GCC 5.3 を使用した 64 ビット Win 7 の MinGW-w64 で見られるのと同じエラーが発生します。