2016-07-15 10 views
6

次のコードでは、列挙メンバmを定数式、つまりテンプレートパラメータとして使用しています。コードはgccでコンパイルされますが、clangではコンパイルされません(live demo)。 Clangは "エラー:非型テンプレート引数は定数式ではありません"と述べています。定数式としてenumを使用します。どのコンパイラが正しいのですか?

この問題は、// 1A<tst<p>::m> aと交換することで解決できます。したがって、私の質問はどのようにこの問題を修正するのではなく、どのコンパイラが正しいです。

template<size_t n> struct A{}; 

template<size_t n> 
struct tst 
{ enum : size_t { m= n % 15 }; 

    template<size_t p> 
    void 
    call(tst<p> const &t2) { 
     A<t2.m> a; // 1 
    } 
}; 
+0

(非公開列挙体がクラスメンバである場合、その列挙子はクラスメンバアクセス演算子 '.'を使用してアクセスできます。と ' - >' "です。それは定数表現であることについて何も言及していない。 –

+1

@JoachimPileborg標準 '§7.2.2'では、' 列挙子リスト内の識別子は定数として宣言され、定数が必要な場所には表示されます。 ' – lcs

答えて

3

標準に従って、Clangはコードを拒否することができます。

t2.mは、クラスメンバーアクセス式です。 [expr.ref]/1は言う:ノートもあります

[...] The postfix expression before the dot or arrow is evaluated; the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.

If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

だから、部分式t2が評価されます。 【expr.const] /2.9発現eはそう、それを評価すること

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either

  • it is initialized with a constant expression or
  • its lifetime began within the evaluation of e ;

t2の評価になる場合、コア定数式で弾丸を満たさない参照型の変数を参照することができないと言いますt2.mはコア定数式ではないため、定数式ではありません。


N4594、現在公表ワーキングドラフトからのすべての引用符。テキストはC++ 11以降わずかに変更されていますが、この場合の意味は同じです。

+0

Thx。誰かがgccのバグレポートを提出しましたか? –

+0

@ClaasBontus私はしていません。バグデータベースの検索は順調ですが、これまでにこれを行う時間はありませんでした。 – bogdan

+0

可能性があります[Bug 39970](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39970)。 –

関連する問題