web-dev-qa-db-ja.com

C ++ 14では、新しい式の次元でdoubleを使用することは有効ですか?

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で何が変更されましたか?

42
Shafik Yaghmour

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

44
Shafik Yaghmour

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ドラフトから欠落しています。

1
gsamaras