5

よくわからないコードに出くわしました。これを簡略化したバージョンを次に示します。

template <int> struct A {};

int const i = { 42 };
typedef A<i> Ai;

int const j = 42;
typedef A<j> Aj;

このコードは C++98 モードの GCC でコンパイルされますが、Clang ではコンパイルされません。Clang は次のエラーを生成します。

$ clang -Wall -Wextra -std=c++98 -c test.cpp

test.cpp:4:11: error: non-type template argument of type 'int' is not an integral constant expression
typedef A<i> Ai;
          ^
test.cpp:4:11: note: initializer of 'i' is not a constant expression
test.cpp:3:11: note: declared here
int const i = { 42 };
          ^

私が理解している限り、int中括弧ありとなしの初期化は同等である必要があります。Clangiは に正しく初期化され42ますが、それがコンパイル時の定数であるとは考えていません。

このコードは、C++11 モードで適切にコンパイルされます。

jコンパイル時定数として扱われる理由とそうでない理由はiありますか? それとも単に Clang のバグですか?

更新:この問題について、LLVM バグ トラッカーでチケットをオープンしました。

4

3 に答える 3

6

はい、C++98 8.5/13 に従って、両方の宣言は同等です。

がスカラー型の場合T、フォームの宣言

T x = { a };

と同等です

T x = a;

したがって、両方の変数は定数であり、定数式から初期化されるため、(私が見る限り)両方とも定数式として使用できるはずです。

于 2013-12-18T16:27:04.773 に答える
2

コンパイラエラーは"template argument of type 'int' is not an integral constant expression"int const i = { 42 };

98 標準によると、テンプレート引数は次のカテゴリに分類されます。

14.3.2 / 1

非型、非テンプレートのテンプレート パラメータのテンプレート引数は、次のいずれかになります。

  • 整数型または列挙型の整数定数式。また

...

整数定数式の定義は、次のint const iカテゴリに分類されます。

5.19 定数式

整数定数式には、リテラル (2.13)、列挙子、const 変数、または静的データ メンバーのみを含めることができます。

および(Mike Seymourの投稿のように)の初期化用i

8.5 初期化子 /13

T がスカラー型の場合、次の形式の宣言

T x = { a };

と同等です

T x = a;

この投稿に基づいて、 const intandの宣言はint const同じである必要があります (標準では特にこれを見つけることができませんでした) const variableiを作成します。したがって、 の使用は、初期化方法に関係なく、整数の定数式である必要があります。clang にバグがあるようです。ウェブをチェックすると、多かれ少なかれ似たバグレポートが2つしか見つかりませんでした:i

http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666539

http://lists.cs.uiuc.edu/pipermail/llvmbugs/2011-March/017353.html

于 2013-12-18T17:45:55.323 に答える