C++ 14では、次のコードが提供されます。
void foo() {
double d = 5.0;
auto p1 = new int[d];
}
clangは診断なしでこれをコンパイルしますが、gccは次の診断を生成します( godboltでのライブを参照 ):
error: expression in new-declarator must have integral or enumeration type
7 | auto p1 = new int[d];
| ^
C++ 11モードではclangがこれを不正な形式として扱い、次の診断を生成するため、このC++ 14に特にラベルを付けました( godboltでのライブを参照 ):
error: array size expression must have integral or unscoped enumeration type, not 'double'
auto p1 = new int[d];
^ ~
Clangは正しいですか?もしそうなら、これを許可するためにC++ 14で何が変更されましたか?
Clangは正しいです。 [expr.new] p6 のキーワードは、C++ 11ドラフトの次のものから変更されています。
noptr-new-declaratorのすべてのconstant-expressionは整数定数式([expr.const])であり、評価する厳密に正の値に。 noptr-new-declaratorの式は、整数型、スコープなし列挙型、または単一の非-整数またはスコープなしの列挙型への明示的な変換関数が存在します([class.conv])。式がクラス型の場合、その変換関数を呼び出すことにより式が変換され、変換の結果が元の式の代わりに使用されます。 …
to C++ 14ドラフトではこれ :
noptr-new-declarator内のすべてのconstant-expressionは、型の変換された定数式([expr.const])でなければならない
std::size_t
そして、厳密に正の値に評価されるものとします。 noptr-new-declaratorの式は、暗黙的にstd::size_t
に変換されます。 …
C++ 14では、noptr-new-declaratorの式の要件が弱くなり、積分、スコープなし列挙、または単一の非明示的な変換関数を持つクラスが不要になりました。これらのタイプのいずれかに変更しますが、size_tへの暗黙的な変換のみを許可します。
言葉遣いの変更は、提案から来ました 特定のC++コンテキスト変換を微調整する提案、v 。
c ++ 14 から c ++ 17 (私のように不思議な人のために)から、フレージングは実質的に同じままです(C++ 11からC +とは異なります) +14 @ShafikYaghmourが答えたように)、これに記載されているように C++ 17ドラフト :
noptr-new-declarator内のすべてのconstant-expressionは、タイプ
std::size_t
の変換された定数式であり、厳密に正の値に評価されます。 noptr-new-declaratorの式は、暗黙的にstd::size_t
に変換されます。 [..]
この部分のみ([expr.const])
がC++ 17ドラフトから欠落しています。