次のスニペットを検討してください。
#include <iostream>
template <int I>
constexpr int f() { return I * f<I-1>(); }
template<>
constexpr int f<0>() { return 1; }
int main () {
std::cout << f<5>();
return 0;
}
このコードは、g++ と clang の両方で適切にコンパイルされます。非常に素晴らしい。static
次に、テンプレート関数の特殊化に追加します。
template<>
constexpr static int f<0>() { return 1; }
次に、g++ 6.1 はエラーで反応します。
11 : エラー: 明示的なテンプレートの特殊化は、ストレージ クラスを持つことはできません
そしてclang 3.8も:
11 : エラー: 明示的な特殊化に無関係で一貫性のないストレージクラス 'static' があります
彼らは一致しているように見えます。とても素敵です。static
ここで、テンプレート関数の一般的なケースにもキーワードを追加します。
g++ 6.1:
11 : エラー: 明示的なテンプレートの特殊化は、ストレージ クラスを持つことはできません
clang 3.8 は警告付きでコンパイルされます。
11 : 警告: 明示的な特殊化はストレージ クラスを持つことはできません
そしてclangの結果は正しい答えを返します。
これはclangのバグですか?そうでない場合、どのような場合にエラーをスローしないことが理にかなっていますか?