この単純なスニペットを見てください:
enum class Enum1 { Value };
enum class Enum2 { Value };
template <auto> struct Foo;
template <> struct Foo<Enum1::Value> { };
template <> struct Foo<Enum2::Value> { };
Clangはこれをコンパイルしますが、gcc-7.2は失敗します:
x.cpp:5:20:エラー: 'struct Foo <(Enum1)0>'テンプレート<> struct Foo {}の再定義;
5行目と同様に、このエラーメッセージは無効のようEnum2::Value
です。
どのコンパイラが正しいですか?これは準拠コードですか?
T
プレースホルダータイプを含むタイプ、および対応する初期化子はe
、次のように決定されます。
- 非型テンプレートパラメータがプレースホルダタイプを含むタイプで宣言するために、
T
非型テンプレートパラメータの宣言された型であり、e
対応するテンプレート引数です。
これは、推定されたタイプがdecltype(Enum1::Value)
であり、値がであると示唆しているようEnum1::Value
です。
あるdecltype(Enum1::Value)
に等しいですかdecltype(Enum2::Value)
?このコード...
static_assert(std::is_same_v<decltype(Enum1::Value), decltype(Enum2::Value)>);
... clang ++ 6とg ++ 8の両方でコンパイルに失敗します。
私は考えてあなたがいることかもしれませんgccのバグを公開しています。ヨハネス・シャウブはコメントで指摘し、またありますGCCの行動を支持して段落が。
開いているバグレポートがあります:#79092。
また、次のコードは両方のコンパイラで受け入れられることに注意してください。
template <typename T, T> struct Foo;
template <> struct Foo<decltype(Enum1::Value), Enum1::Value> { };
template <> struct Foo<decltype(Enum2::Value), Enum2::Value> { };
template <auto>
それとは異なる振る舞いをすることは、(IMHO)驚きであり、望ましくないことです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加