次のコードはClangでコンパイルされますが、GCCではコンパイルされません。
template<typename T>
struct Widget
{
template<typename U>
void foo(U)
{
}
template<>
void foo(int*)
{
}
};
C++標準([temp.expl.spec]、段落2)によると:
明示的な特殊化は、対応するプライマリテンプレートを定義できる任意のスコープで宣言できます。
これはGCCのバグですか?もしそうなら、バグトラッカーでどのように見つけることができますか?
これはGCCの出力です:
prog.cc:13:14: error: explicit specialization in non-namespace scope 'struct Widget<T>'
template<>
^
私はGCCを使用していますHEAD 8.0.1、with -std=c++2a
。
これはGCCのバグであるはずです。クラス定義を含め、すべてのスコープで完全な特殊化を許可する必要があります。
CWG 727 によると、[temp.expl.spec]段落2はから変更されました
(私の強調)
明示的な特殊化は、特殊化されたテンプレートを囲む名前空間で宣言する必要があります。 declarator-idまたはclass-head-nameが修飾されていない明示的な特殊化は、テンプレートの最も近い囲んでいる名前空間、または名前空間がインライン(10.3.1 [namespace.def])の場合は、その名前空間からの任意の名前空間で宣言されるものとします。名前空間セットを囲みます。そのような宣言も定義かもしれません。宣言が定義でない場合、特殊化は後で定義できます(10.3.1.2 [namespace.memdef])。
に
(私の強調)
明示的な特殊化は、対応するプライマリテンプレートを定義できる任意のスコープで宣言できます(10.3.1.2 [namespace.memdef]、12.2 [class。 mem]、17.6.2 [temp.mem])。
GCCはこれに従わないようです。
[〜#〜]編集[〜#〜]
私はこの問題を バグ85282 として報告しました。