2014年7月14日月曜日

C++11 における 5.2.3 明示的な型の変換 ( 関数っぽい記法 ) [expr.type.conv]

こんなやりとりがTwitterでありました。

https://twitter.com/k_satoda/status/488478046295699456

と、いうわけで、この際なので C++11規格書の 5.2.3 を読んでみる。(正確にはここで私が事実上のC++11として参照するのは一般公開されているドラフト版のN3337です。)
5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
5.2.3 明示的な型の変換 ( 関数っぽい記法 ) [expr.type.conv]
A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list.
simple-type-specifier (7.1.6.2) または typename-specifier (14.6) は丸括弧入りの expression-list によりその型の値を expression-list に応じて構築しますよ。

※訳注1: simple-type-specifier は bool とか int のこと。
※訳注2: type-specifier は class とか enum で定義した型のこと。
※訳注3: expression-list は f( a, b, c ) の a, b, c の式のリストのこと。
If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
もし expression-list が単独の式の場合、その型変換式はキャスト式 (5.4) と等価 ( 明確には、その意味で定義されていれば ) ですよ。

※側註a: ちなみに 5.4 Explicit type conversion ( cast notation ) [expr.cast] でも特に functional notation を使ったらどうという事は定義されていません。 
If the type specified is a class type, the class type shall be complete.
もし型が class 型の場合、その class 型は完全じゃなきゃダメよ。
If the expression list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1), and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as a prvalue.
もしその expression-list が複数の値からなる場合に、その型が適合するコンストラクター ( 8.5, 12.1 ) が宣言された class なら、この式 T( x1, x2, ... ) は T t( x1, x2, ...) の宣言と等価だよ。; ここで作られる一時的な変数 t は、結果的に prvalue の値になるよ。

※訳注4: prvalue は一時的に生成されるオブジェクトこと。
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type,which is value-initialized (8.5; no initialization is done for the void() case). [ Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting prvalue (3.10). — end note ]
その式 T() について、但し T が simple-type-specifier または typename-specifier の非配列な完全なオブジェクトの型か( あるいはcv修飾付きの ) void 型  なら、 その型の prvalue を初期化して生成しますよ( 8.5; void() の場合には初期化しないで完了するけど)。[ 注: もし T がcv修飾付きの非 class 型なら、そのcv修飾は結果得られる prvalue ( 3.10 ) では無効化されるからね。 ― 注終わり]
Similarly, a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list, and its value is that temporary object as a prvalue.
同様に、 simple-type-specifier または typename-specifier について braced-init-list によってもその braced-init-list によって direct-list-initialized ( 8.5.4 ) された prvalue なその型の一時オブジェクトが得られますよ。

※訳注5: braced-init-list は { } によるオブジェクト初期化の expression-list の記述。
※訳注6: direct-list-initialized は T t = { 1u, 2.f, "hoge" } のように braced-init-list から直接オブジェクトを構築するってこと。

と、言うわけで、 @k_satoda さんが指摘してくれたように、C++言語規格としては type(value) (5.2.3) は (type)value ( 5.4 ) と等価で static_cast<type>(value) になるとはどこにも書いてないのでした。

私の場合、いつか誰かに聞いて規格を確認しないままそーなのかーと間違えて覚えたままになっていました。ご指摘ありがとうございました(╹◡╹)

0 件のコメント:

コメントを投稿