8

次のコードは、テンプレートを宣言し、明示的なインスタンス化定義を宣言してから、明示的なインスタンス化宣言を宣言します。

template <typename T>
T Double(T number)
{
    return number * 2;
}

extern template int Double<int>(int);  // declaration
template int Double<int>(int t);       // definition

int main(int argc, char* argv[])
{
    int n = Double(10);

    return 0;
}

エラーが発生します:

error C2929: 'int Double<int>(int)' : explicit instantiation; cannot explicitly force and suppress instantiation of template-class member

Visual Studio 2012 で。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htmから、定義は宣言に従うため、これは有効であるという印象を受けています。

何か不足していますか?

4

3 に答える 3

7

あなたのプログラムは整形式です。C++11 標準のパラグラフ 14.7.2/11 では、次のように指定されています。

エンティティが、同じ翻訳単位内の明示的なインスタンス化宣言と明示的なインスタンス化定義の両方の対象である場合、定義は宣言に従うものとします。[...]

あなたのプログラムはこの制約を尊重し、他の規則を破ることはありません。したがって、これは VC11 のバグとみなされます。

于 2013-05-28T17:26:38.237 に答える
3

この Visual C++ 準拠のバグは、こちらから入手できる Visual Studio 2013 で対処されています。この修正によりextern template、ヘッダー ファイルに宣言を配置してテンプレートのインスタンス化を抑制し、1 つのモジュールで明示的なインスタンス化を宣言できるようになり、コンパイル時間とコードの肥大化を削減できます。ステートメントを逆にすると (つまり、明示的なインスタンス化要求の後extern templateに同じテンプレート引数を使用した宣言が続く)、エラー C2929 が発生します。これは、既に明示的にインスタンス化したものを抑制しようとしているように見えるためです。

于 2013-09-24T19:50:29.307 に答える
3

この問題はMicrosoft Connect 620017に報告されたようです:

Microsoft によって 2010 年 12 月 3 日午後 1 時 52 分に投稿されました。

こんにちは、

ご指摘のとおり、extern テンプレートの実装は C++-0x 標準に準拠していません。古い拡張機能の実装がまだ残っています。Visual Studio の次のリリースでこの機能の C++-0x バージョンを実装するためのリソースはありませんが、適合性の問題は優先事項です。現在、Visual Studio の将来のバージョンでこの機能を実装する予定です。

この問題を報告していただきありがとうございます。感謝しています。

Jamie Eckman Visual C++ チーム

それは 2010 年のもので、「次のリリース」とは VS2012 を意味していました。

于 2013-06-18T12:02:36.487 に答える