X 3014
:2003 (
ISO/IEC 14882
:2003)
(
1
)
まえがき
この規格は,工業標準化法第
12
条第
1
項の規定に基づき,社団法人情報処理学会
(IPSJ)
/財団法人日本
規格協会
(JSA)
から,工業標準原案を具して日本工業規格を制定すべきとの申出があり,日本工業標準調査
会の審議を経て,経済産業大臣が制定した日本工業規格である。
制定に当たっては,日本工業規格と国際規格との対比,国際規格に一致した日本工業規格の作成及び日
本工業規格を基礎にした国際規格原案の提案を容易にするために,
ISO/IEC 14882
:2003
,
Information
Technology
―
Programming languages
―
C++
を基礎として用いた。
著作権法により無断での複製,転載等は禁止されております。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
日 本 工 業 規 格
プ ロ グ ラ ム 言 語
序文
この規格は,
年
月に発行された
!
"##
の第
版を翻訳し,技術的内容及び規格票の様式を変更することなく作成した日本工業規格である。
なお,下線を施してある箇所は,この規格で定義する用語である。側線を施してある
参考
は,原国際規格にはない
事項である。
総則
適用範囲
この規格は,プログラム言語
"##
の処理系に対する要件を規定する。処理系は,その第
要件と
して,
"##
を実装しなければならない。このため,この規格は,プログラム言語
"##
の定義もあわせて規定する。
その他の要件 及び 第
要件に対する緩和条項は,この規格の中で順次規定する。
プログラム言語
"##
は,
6
によるプログラム言語
"
に基づく。
"##
は,
"
が提供する機能に
加えて,幾つかのデータ型,クラス,テンプレート,例外,名前空間,インライン関数,演算子の多重定義,関数名
の多重定義,参照,空き領域管理用の演算子,及び 幾つかのライブラリを提供する。
引用規格
この規格の規定の一部となる規定をもった規格の一覧を,次に示す。
―
( 規格群全体)
$
%
備考
情報処理用語の規格
6
〜
が,この引用規格群と一致している。
―
6
プログラム言語
"
備考
***
!
"
が,この引用規格と一致している。
―
6
&'()*'()+
プログラム言語
"
( 追補
)
備考
*** 3
!
",
&'()*'()+
"
-
が,この引用規格と一致している。
―
6
!
国際符号化文字集合(
."/
)
第1部
体系及び基本多言語面
備考
((!
.0
!
' 1-2
"
33
"-
/
."/
&
3
4!
'
が,この引用規格と
一致している。
参考
関連規格を,次に示す。
―
(##*
4
5-1
1
!!
!!!
備考
この規格の旧番号は,
##*
であった。この規格は,
30
)#-
(((
!33
%
5
1
と一致している。
―
6
移植可能なオペレーティングシステムのインタフェース(
2/6
)
第
1部
応用プログラム向けのインタフェース(
&
)
[プログラム言語C]
備考
**#!
%
21
/!
-
2/6
/!
&11
&
7"
8 9
が,この引用規格と一致している。
―
6
移植可能なオペレーティングシステムのインタフェース(
2/6
)
第
2部
シェル及びユーティリティ
備考
**#!
%
21
/!
-
2/6
/
3
.!
が,この引用規格と一致している。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6
の
)
及び
6
&'()*'()+
の
)
によるライブラリを,この規格で
は標準
"
ライブラリ
と呼ぶ。
用語の定義
この規格で用いる主な用語の定義は,
によるほか,
〜
のとおりとす
る。
)
〜
)
だけで用いる用語については,
)
に定義する。
この規格の一部でだけ用いる用語は,それぞれ必要な箇所で定義する。そうした定義の対象となる用語は,下線に
よって示す。
実引数
関数呼出し式の括弧の中にコンマで区切られて並んだ式,関数形マクロ呼出しの括弧
の中にコンマで区切られて並んだ前処理字句の列,
の演算対象,又は テンプレート具現化の三角括弧の中にコ
ンマで区切られて並んだ型識別子 若しくは テンプレート名。
診断情報
処理系が出力する処理系定義の出力情報の一つ。
動的な型
左辺値式の表す左辺値が指す最派生オブジェクト(
)の型。
例
その静的な型が
:
クラス
"
へのポインタ
;
であるポインタ(
)
が,クラス
"
から派生した(
)ク
ラス
#
のオブジェクトを指していたとすると,式
!
の動的な型は,
:#;
となる。参照(
)も,同様
に扱う。
右辺値式の動的な型は,それの静的な型とする。
不適格プログラム
!"
適格プログラム(
)でない
"##
処理系への入力。
#
処理系定義の動作
!$
%
&
'
適格プログラムの構文単位と 正しいデータと
の組合せに対する,処理系に依存した動作であって,それぞれの処理系が文書で説明を用意しておかなければならな
い動作。
(
処理系限界
処理系がプログラムに課している制限。
)
文化圏固有動作
!
$
%
&
'
国,文化,言語などに依存した動作であって,それぞれの処理
系が文書で説明を用意しておかなければならない動作。
多バイト 文字
!%
&
翻訳環境 又は 実行環境での拡張文字集合の要素を表した
バイト
以上のバイト列。拡張文字集合は,基本文字集合をその部分集合としている(
参照)
。
*
仮引数
次のいずれかとする。
―
関数宣言 若しくは 関数定義の中,又は 例外処理部の
節の中で宣言され ,その関数 又は 例外処理
部が起動する際に値を受け取るオブジェクト 又は 参照
―
関数形式マクロの定義の中で,そのマクロ名に続く括弧の中にコンマで区切られて並んでいる識別子
―
テンプレート仮引数
呼出し情報
関数について,その多重定義解決(
)に用いる情報。基本的には,その関数
の仮引数の型の列。関数がクラスのメンバである場合は,関数自身の
0
修飾子 及び それを宣言しているクラスも含
める
。関数テンプレートの特殊化に対する呼出し情報では,テンプレート実引数の型も含める(
##
参照)
。
静的な型
式(
*
)の型。その式がもたらす結果の型として,実行時の意味を考慮せずにプ
ログラムを解析することで得られる。式の静的な型は,その式が位置するプログラムの形だけから決まり,プログラ
ムの実行中に変わることがない。
未定義の動作
$
%
&
'
間違いを含んだプログラム,間違ったデータ などに対して生じ うる
動作であって,この規格で要件を規定しない動作。この規格で動作を明示的に与えていない場合も,未定義の動作と
する。
参考
未定義の動作としては,次のものがありうる。
―
その状況を完全に無視し ,何が起きるかわからない。
―
翻訳段階 又は プログラムの実行段階で,その環境に沿っての動作をする( 診断情報を出して
もよいし,出さなくてもよい。)
。ただし ,その動作の様子については,文書を用意して説明し
ておく。
―
翻訳 又は 実行を終了する( 診断情報を出力する。)
。
間違いを含んだプログラムの多くは,未定義の動作を引き起こすことがない。それらに対しては,診断を
下すことを要求している。
注
〜
及び
にあるとおり,標準
ライブラリは,標準
ライブラリの部分集合となっている。
注
関数の呼出し情報には,返却値の型が含まれていない。多重定義の解決には,返却値の型が関与しないからである。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
未規定の動作
$
%
&
'
適格プログラムと正しいデータとの組合せに対する動作であって,
処理系に依存する動作。処理系は,どんな動作が生じるかについて文書を用意する必要はない。
参考
多くの場合,どんな動作が生じ うるかについて,この規格の中で示唆する。
適格プログラム
+
!"
構文規則,診断対象の意味規則,及び 単一定義規則(
参照)
に従った
"##
プログラム。
処理系の適合
この規格の構文規則 及び 意味規則は,
:
診断を必要としない
;
と明記してある規則,及び
:
動作
は未定義とする
;
と明記してある規則を除いて,すべて診断対象規則
3!%
とする。
この規格は,
"##
処理系に対する要件を規定する。しかしながら,それらの要件は,多くの場合,プログラム,プ
ログラムの部分,又は プログラムの実行に対する要求事項の形をとる。こうした要求事項は,次の意味をもつ。
―
プログラムがこの規格に示す規則に違反していない場合,適合する処理系は,その資源的な限界の範囲内
で,そのプログラムを受理し ,正しい実行
を行わなければならない。
―
プログラムが診断対象でない規則に
カ所でも違反している場合,この規格は,そのプログラムに対する
処理系の処置に何らの要件もおかない。
―
プログラムが診断対象規則に違反している箇所がある場合,適合する処理系は,それぞれの箇所ごとに,
少なくとも何らかの診断情報を出力しなければならない。ただし ,そのプログラムが診断対象でない規則
にも違反している場合は,この限りでない。
クラス 及び クラステンプレートに対しては,ライブラリ条項(
#
)でその定義を部分的に規定する。すなわち,
非公開メンバ(
)の定義は,規定しない。
( 適合する)処理系は,ライブラリ条項に従って非公開メンバの定義を
与え,クラス 及び クラステンプレートの定義を完成しなければならない。
関数,関数テンプレート,オブジェクト 及び 値に対しては,ライブラリ条項でその宣言を規定する。
( 適合する)
処理系は,ライブラリ条項に従ってその定義を与えなければならない。
ライブラリが定義する名前は,名前空間の有効範囲(
)
)をもつ。
"##
翻訳単位(
)では,そこに適切な標
準ライブラリのヘッダを取り込むことによって,これらの名前を使うことができる(
(
参照)
。
ライブラリの中の テンプレート,クラス,関数 及び オブジェクトは,外部結合(
#
)をもつ。
( 適合する)処理
系は,翻訳単位を結合して完全な
"##
プログラムを構成する際に,必要に応じて,標準ライブラリのこれらに対す
る定義を提供しなければならない(
参照)
。
処理系を,依存処理系
!3
1
と自立処理系
!3
1
とに分類する。依存
処理系は,
2/
の下で動作する処理系をいう。自立処理系は,
2/
の助けなしで動作する処理系をいう。依存処理系が
提供しなければならないライブラリは,そのすべてをこの規格で規定する。自立処理系が提供するライブラリは,処理
系定義とする。その提供するライブラリには幾つかの言語常備ライブラリが含まれていなければならない(
)
参照)
。
適合する処理系は,適格プログラムの動作を変えることがない限り,拡張(ライブラリ関数の追加を含む。)を行っ
てもよい。
( 適合する)処理系は,プログラムがこの規格で不適格であれば,こうした拡張を使っていても,診断情報
を出力しなければならない。診断情報を出力しさえすれば ,そうしたプログラムを翻訳し実行しても差し支えない。
#
この規格の構成
〜
(
にプログラム言語
"##
の仕様を規定する。そこでは,構文の仕様を
(
の記法で
与える。すべての構文の仕様は,便宜を図って,
附属書
3
に再掲する。
)
〜
)
( ライブラリ条項
%
!!
と呼ぶ。)に,標準
"##
ライブラリを規定する。そこでは,マクロ
(
(
),値(
),型(
及び
参照),テンプレート(
),クラス(
*
),関数(
#
) 及び オブジェク
ト(
)
)に対する定義を規定する。
附属書
4
に,適合する処理系の最小能力の推奨例を示す。
附属書
に,最初の版からの
"##
の変遷,及び
"##
と
"
言語との差異の詳細を示す。幾つかの
"##
の機能
は,こうした経緯との両立性を保つためだけに設けてある。
附属書
5
にこれらの機能を示す。
附属書
に,
"##
の識別子(
)に使える文字を,その国際文字名で示す。
この規格では,例を示す場合,字下げした太字の
例
で始める。参考を示す場合,字下げした太字の
参考
で始める。
例と参考とは,互いに入れ子になることがある。
(
構文記法
この規格で用いる構文記法では,構文要素( 非終端記号)の名前を《日本語文字》でつづって表し ,
終端記号をタイプライタ体で表す。選択肢は,原則として,それぞれ単独の行として並べる。ただし,多数の選択肢
がある場合に,
:
次のいずれか
;
と明記した上で,選択肢を列挙することがある。このとき,
行に複数の選択肢を並
注
正しい実行
には,処理するデータにもよるが,未定義の動作も含まれる(
及び
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
べることもある。省略可能な終端記号 又は 非終端記号には,
:1;
を下付けする。例えば ,次のものは,波括弧の
中に式を
個書いたものか,波括弧だけを書いたものを表す。
式
構文要素名は,次の原則に従っている。
―
:
《…… 名》
;
は,文脈から意味が決まる識別子の使用に当てる(例えば,
《クラス名》,
《型定義名》など )
。
―
:
《…… 識別子》
;
は,文脈に依存しない識別子に当てる( 例えば ,
《修飾付き識別子》)
。
―
:
《…… 列》
;
は,区切りなしに並べたものに当てる( 例えば ,
《宣言列》は,宣言を並べたものを表す。)
。
―
:
《…… 並び》
;
は,コンマで区切って並べたものに当てる( 例えば ,
《式並び》は,式をコンマで区切っ
て並べたものを表す。)
。
)
,,
記憶モデル
"##
では,その基本の記憶単位をバイト
%
と呼ぶ。バイトは,基本実行文字集合の文
字を収めることができる大きさをもつ,一連のビット列とする。そのビット数は,処理系定義とする。その重みの最
も大きいビットを上位ビット
-3
%
と呼び,最も小さいビットを下位ビット
<-3
%
と呼ぶ。
"##
プログラムでは,その記憶として,連続したバイトからなる
個以上の列を使う。それぞれのバイトは,固有の番地
をもつ。
参考
型の表現は,
*
で規定する。
,,
オブジェクト モデル
"##
プログラムの構文単位は,オブジェクトを生成し,破壊し,参照し ,取り出
し ,加工する。オブジェクト
%
=
は,記憶域からなる。
参考
関数は,オブジェクトではない。オブジェクトと同様に記憶域を占有することもあるが,しないことも
ある。
オブジェクトは,
《定義》
3>
(
) 又は 《
<
式》
(
#
)が生成する。更に,必要に応じて処理系が生成す
る(
参照)
。オブジェクトの特性は,その生成時に決まる。オブジェクトは,名前
をもつことがある。オ
ブジェクトは,記憶域期間
!
3
(
)
)をもつ。記憶域期間は,そのオブジェクトの生存期間
(
)を左右する。オブジェクトは,型
1
(
*
)をもつ。オブジェクト型
%
=
1
とは,そのオブジェク
トを生成するのに用いた型をいう。オブジェクトには,多相のオブジェクトがある。多相オブジェクト
1
1
%
=
に対しては,実行時にそのオブジェクトの型が決定できるだけの必要な情報を処理系が生成する。多相でない
オブジェクトでは,そのオブジェクトの中の値の解釈が,それを取り出すのに用いる式
?1!!
の型によって定
まる。
オブジェクトが他のオブジェクトを包含することがある。この包含されたオブジェクトを,部分オブジェクト
! %-
%
=
と呼ぶ。部分オブジェクトには,メンバ部分オブジェクト
%
! %-%
=
(
*
),基底クラス部分オ
ブジェクト
%!
!!
! %-%
=
(
)及び 配列要素がある。他のオブジェクトの部分オブジェクトとなっていな
いオブジェクトを,総体オブジェクト
1
%
=
と呼ぶ。
それぞれのオブジェクト
に対して,
の総体オブジェクトとは,次で定まるオブジェクトをいう。
―
が総体オブジェクトの場合,
自身。
―
そうでない場合,
を包含しているオブジェクト(これは一意に定まる。)の総体オブジェクト。
クラス型の,総体オブジェクト,データメンバ(
*
) 又は 配列要素の型としては,基底クラス部分オブジェクト
のクラス型と区別するため,その最派生クラス
!
30
3
!!
を採択する。最派生クラス型のオブジェクトを,
最派生オブジェクト
!
30
3
%
=
と呼ぶ。
最派生オブジェクトは,それがビットフィールド(
*(
)である場合を除いて,ゼロでない大きさをもち,
バイト
以上の記憶域を占める。基底クラス部分オブジェクトは,大きさがゼロであることがある。
"
互換型(
2*
型,
*
参照)のオブジェクトは,一連のバイトからなる記憶域を占める。
参考
"##
は,種々の組込みの型とともに,既存の型を組み合わせて新しい型を構成する複数の手段を提供
する(
*
参照)
。
*
プログラムの実行
この規格では,意味を規定するのに,パラメタをもった非決定性の抽象機械を用いる。この
規格は,適合する処理系に対して,その構成方法に関する何らの要件も置かない。したがって,この抽象機械の構成
を模倣する必要もない。適合する処理系は,この抽象機械の外から見た動作(だけ )を模倣しなければならない。
注
は,
の略号である。
注
この規定は,
まるで
規則とも呼ばれることがある。処理系は,まるで すべての要件を満たしているように,プログラムの外
から見た動作をもたらすのであれば,この規格が規定する具体的要件そのものを無視して差し支えない。例えば,処理系は,式の値が使
われることがなく,しかもプログラムの外から見た動作に影響を与えるような副作用をもたないと帰結できるのであれば,その式の評価
を行わなくてもよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
抽象機械の性質 及び 操作( 例えば ,
$
)を,処理系定義と規定することがある。これらは,抽象機械
のパラメタとなる。個々の処理系は,これらの性質に対して,その特性 及び 動作を記した文書を提供しなければな
らない。これらの文書によって,その処理系に呼応した抽象機械が定まる( 以後,これを呼応抽象機械と呼ぶ。)
。
抽象機械の特質 及び 操作( 例えば ,関数の実引数評価の順序)を,処理系依存と規定することがある。この規格
では,可能な限り,その許容可能な一連の動作を示す。これらは,抽象機械に非決定性をもたらす。呼応抽象機械で
は,したがって,特定のプログラムと入力の組合せに対して複数の実行列が生じ うる。
また,操作( 例えば ,空ポインタの参照はずしの効果)によっては,未定義と規定することもある。
参考
この規格は,未定義の動作を含むプログラムの動作に対して,何らの要件をおかない。
適合する処理系は,適格プログラムを実行した結果,同じプログラムと入力の組合せに対する呼応抽象機械がもた
らす実行列の一つと,外から見て同じ動作をもたらさなければならない。しかし,その実行列が未定義の操作を含む
場合,この規格は,適合処理系がそのプログラムと入力の組合せをどのように実行するかについて(その最初の未定
義の操作が生じる前の操作に関しても),何らの要件も置かない。
抽象機械の外から見た動作とは,揮発性データに関する読み書き,及び ライブラリ入出力関数
呼出しの系列を
いう。
揮発性左辺値(
)が指すオブジェクトの取出し ,オブジェクト一般の加工,ライブラリ入出力関数の呼出し ,
及び これらの操作を含んだ関数の呼出しを,副作用
!3-@
と呼ぶ。副作用は,実行環境の状態に変化をもたら
す。式の評価が副作用をもたらすこともある。実行列中の幾つかの点を特定して副作用完了点
!A
1
と呼
ぶ。副作用完了点では,その副作用完了点以前の操作すべての副作用が完了するまで,それ以後の操作の副作用が生
じてはならない。
関数の実行が始まると,その関数を呼び出した式の評価は,その関数が完了するまで休止する。
抽象機械がシグナルを受け取ってその処理を中断した場合,型
以外の型のオブジェクト
の値は,未規定とする。さらに,例外処理部が変更を加えた,
以外の型のオブジェクトの値
は,未定義とする。
ブロックに入るごとに,その自動記憶域期間(
)
)をもったオブジェクトを具体的に生成する。こうしたオブ
ジェクトは,そのブロックの実行中,及び そのブロックの( 関数の呼出し 又は シグナルの受取りによる)実行保留
の間存在し,最近に代入された値を保持する。
適合する処理系は,少なくとも次の要件を満たさなければならない。
―
副作用完了点では,揮発性オブジェクトが安定であること。すなわち,それ以前の評価が完了し ,以後の
評価がまだ始まっていないこと。
―
プログラム終了時点では,ファイルに書き出したデータが,そのプログラムの抽象機械による実行結果の
一つと一致していること。
―
対話装置の入出力では,プログラムが入力待ちに入る前に,それに対する入力要求が表示されること。対
話装置が何であるかは,処理系定義とする。
他の式の部分式となっていない式を完結式
-?1!!
と呼ぶ。暗黙の関数呼出しを生じると規定する構文単
位は,ここでの式として扱い,完結式として扱う。
参考
"##
では,文脈によって《式》以外の構文単位から生じた完結式を評価することがある(
#
参照)
。
例えば ,
#
の《初期化子》の一つに次のものがある。
式並び
この構文単位は,その《式並び》を《実引数並び》としてコンストラクタ関数を呼び出す関数呼出しと
なる。同様に,
《初期化子》の一つに次のものもある。
%
初期化子節
この構文単位も,
個の《代入式》を実引数としてコンストラクタ関数を呼び出す関数呼出しとなること
がある。この場合も,その関数呼出しは,完結式として扱う。
参考
完結式の評価は,その完結式の字句的な部分となっていない部分式の評価を含むことがある。例えば ,
注
処理系は,拡張としてライブラリ入出力関数を追加してもよい。これらを追加したときは,その呼出しも
外から見える動作
として
扱うことが望ましい。
注
抽象機械での操作の実行順序がすべて規定されているわけでない点に注意する必要がある。ここでの制約は,実際に目的プログラムが
生成された場合の,その実行順序での副作用だけを対象とする。ライブラリ入出力関数の呼出しから戻った時点で,その呼出しが引き起
こす外部の動作( 例えば,入出力動作自身)がまだ完了していなくても,その副作用が完了したものとして扱うことにも注意する必要が
ある。
注
すなわち,関数の実行が互いに切り混ざることはない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
省略時実引数の式(
(
)の部分式は,その省略時実引数を定義している式の中ではなく,その関数呼出
しの式の中で作り出される。
参考
演算子の評価順序の整理は,対象となる演算子が実際に結合律 又は 交換律を満たす場合
にだけ,通
常の数学規則に従って行ってよい。例えば ,次のプログラム片を考えてみる。
&
'!(((!'
%
)
*+,-.
)
)
/&
この式は,現れている演算子の順位から正確に次のとおりに振る舞う。
%
)
*+,-.
)
)
/ &
したがって,和
)
*+-,.
に
を加え,その結果に
を加えたものを
に代入する。あふれで例外を
発生し ,しかも
型で表せる値が
7
# 9
である計算機に対して,処理系は,この式を次の
いずれにも書き換えてはならない。
%
)
)
*+,-/ &
%
)
)
*+,-/ &
と
の値が
と
又は
と
である場合に,動作が違ってしまうからである。しかしながら,あ
ふれで例外を発生することがなく,あふれが生じても逆演算で元に戻せる計算機に対してなら,処理系は,
上に示した式をこれら
通りのいずれに書き換えても差し支えない。同じ結果が得られるからである。
完結式の評価完了時点は,それぞれ副作用完了点となる。
関数( インライン関数であるか否かによらない。)の呼出しに対しては,
( もしあれば )その実引数の評価の直後が
副作用完了点となる。実引数の評価は,その関数本体の式 又は 文の実行に先行する。返却値のコピーの後も副作用
完了点となる
。返却値のコピーは,その関数の外側のいかなる式の評価にも先行する。
"##
では,文脈によっ
て,その翻訳単位の中に関数呼出しの構文単位が現れていない場合にも,関数呼出しの評価を行うことがある。
例
<
式の評価では,
個以上の割付け関数 及び コンストラクタ関数を呼び出すことがある(
#
参照)
。
関数呼出しの構文単位が現れていない文脈で,変換関数(
)を呼び出すこともある。
関数呼出しでは,その関数を呼び出した構文が何であれ ,関数に入る時点 及び 関数から出る時点が副作用完了点と
なる。
次の式(
#
,
##
,
#(
及び
#
参照)を考える。
00
11
2
3
現れている組込み演算子の意味に従って評価を行う場合,それぞれ第
演算対象の評価の直後が副作用完了点となる。
告知
この規格で規定するプログラム言語
"##
は,次の本の
B
章
B
'
に基づく。
/ ! 1
+
"##
8
!3
3,
&333-C
!
%!
"1
,
/4)
---,
1
&
+D+E
この本は,更に次の本の
付録
3
に基づいている。
F
3
B
+
"
1
8 ,
-
G,
,
/4)
---,
1
&
+D+E
この規格のライブラリ条項は,次の本に基づく。
E
HE
+
*
/33
"##
8%
,
-G,
/4)
-- -,
1
E
HE
E
これらの書籍の著作権は,保護されている。
注
多重定義してある演算子は,結合律も交換律も満たさないものとして扱う。
注
この
完結式評価完了時点
の副作用完了点の後で,一時オブジェクトに対するデストラクタ関数の呼出しが起きる。その順序は,通
常,一時オブジェクトが生成されたのと逆順となる(
参照)
。
注
関数からの戻り時点での副作用完了点は,
では明示的に規定していない。完結式に対する副作用完了点と重複するから
である。しかし ,
では明確にしておく必要がある。
では,呼び出された関数がその実行を終了するのに,例外を送出するな
ど 複数の方法があるからである。
注
ここでは,組込み演算子(
)が対象となる。その演算子が正当な文脈で多重定義を受け,利用者が定義した関数を表している場合,
これらの式は,書かれた演算対象を実引数とする関数呼出しとなり,ここで示したような副作用完了点をもたない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
字句要素
プログラムの文字面を収めたものを,この規格では,ソースファイル
!
>
と呼ぶ。
個のソー
スファイルを,その前処理指令
によって取り込んだ(
(
参照)ヘッダ(
)
) 及び 他のソースファ
イルも込みにして,翻訳単位
!
と呼ぶ。ただし ,条件付き取込み前処理指令(
(
)によって省か
れた行は,除く。
参考
"##
プログラムは,そのすべてを同時に翻訳する必要はない。
参考
それまでに翻訳した翻訳単位 及び 具現化単位は,個別に保存しておくこともできれば ,ライブラリと
してまとめて保存しておくこともできる。プログラムを構成する個々の翻訳単位は,例えば外部結合の識
別子をもつ関数の呼出し ,外部結合の識別子をもつオブジェクトの操作,データファイルの操作などを通
じて,相互に連絡する(
#
参照)
。翻訳単位は,別々に翻訳して,後で実行可能なプログラムへと結合す
ることもできる(
#
参照)
。
翻訳過程
翻訳過程における各構文規則の優先順位は,それぞれの段階に応じて次のとおりとする。
必要に応じて,処理系が定めた方法でソースファイルの物理的文字を基本ソース文字集合の文字に変換す
る( 行末表示は,改行文字に変換する。)。三つ組表示(
)を,対応する内部表現の単一文字に置き換
える。基本ソース文字集合(
)にない文字を,その文字を表す国際文字名に置き換える。
( 処理系は,
拡張文字が直にソースファイルに現れた場合と,その拡張文字を指名する国際文字名(すなわち,
45555
という記法)がソースファイルに現れた場合とを同等に扱う限り,どんな内部表現を用いてもよい。)
逆斜線の直後に改行文字が現れている箇所それぞれで,その逆斜線と改行文字の組を取り除き,物理的な
行を論理的な行にまとめる。この結果として国際文字名がそこに生じた場合,その動作は,未定義とする。
空でないソースファイルが改行文字で終わっていない場合,その動作は,未定義とする。空でないソース
ファイルが逆斜線に続く改行文字で終わっている場合,その動作は,未定義とする。
ソースファイルを,前処理字句(
) 及び 空白類( 注釈を含む。)の列に分解する。ソースファイルは,
部分的な前処理字句 又は 部分的な注釈で終わってはならない
。それぞれの注釈を,
個の空白文字に
置き換える。改行文字は,そのまま残す。改行文字以外の空白類の空でない列をそのまま残すか
個の空
白文字に置き換えるかは,処理系定義とする。ソースファイルの文字の列を前処理字句の列に分解してい
く処理は,文脈に依存する。
例
前処理指令
での
の扱いが参考になる。
前処理指令を実行し,マクロ呼出しを展開する。字句連結(
(
)の結果として国際文字名の構文に合
致する文字の列が生じた場合,その動作は,未定義とする。前処理指令
の実行では,そこで指
示されたヘッダ 又は ソースファイルに対して,それぞれ,
〜
の段階の処理を再帰的に行う。
#
文字リテラル 及び 文字列リテラルの中の,ソース文字集合の文字,逆斜線表記,及び 国際文字名それぞ
れを,実行文字集合(
及び
参照)の文字に変換する。
(
隣り合う( 通常の)文字列リテラルを連結する。隣り合うワイド 文字列リテラルを連結する。
)
この段階以降,字句を区切っている空白類は,意味をもたない。それぞれの前処理字句を字句に変換する
(
(
参照)
。この結果得られた字句の列を,構文解析 及び 意味解析をして翻訳する。
参考
ソースファイル,
( 翻訳前の )翻訳単位 及び 翻訳済みの翻訳単位を物理的なファイルとして
保持する必要はないし ,それぞれに
対
に対応する外部表現が必要なわけでもない。ここで
の規定は,概念上のものであって,具体的な実装を規定するものではない。
翻訳済み翻訳単位 及び 具現化単位
!
を結合する。
参考
これらの一部 又は 全部が,ライブラリの中にあることがある。
まず,それぞれの翻訳済み翻訳単位を調べ,必要な具現化の一覧表を作る。
参考
これには,明示的に要求されている具現化(
)
)も含まれる。
必要なテンプレートの定義を見つけ出す。このとき,これらの定義を含んだ翻訳単位のソースも必要であ
るかど うかは,処理系定義とする。
参考
処理系によっては,ここでソースを必要としないで済ますように,翻訳済み翻訳単位に十分
な情報を組み込んでいる。
注
処理系は,まるでこれらの段階を順に踏んでいるかのごとく振る舞わなければならないが,実際には,いくつかの段階を一緒にまとめ
て行ってもよい。
注
部分的な前処理字句は,例えば,
《ヘッダ名》にその終止文字
又は
がない場合など ,その終止文字列を必要とする複数文字からな
る字句がソースファイルの末尾に現れている場合に生じ うる。部分的な注釈は,閉じていない
注釈がソースファイルの末尾に現れて
いる場合に生じ うる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
必要な具現化すべてを行い,具現化単位を作り出す。
参考
これらは,翻訳済み翻訳単位と同等である。ただし ,具現化されていないテンプレートもテ
ンプレート定義も含んでいない。
*
外部オブジェクト 及び 外部関数への参照を解決する。ライブラリの構成要素を結合することで,その翻
訳の中に定義のない関数 及び オブジェクトの外部参照を解決する。こうして得られた翻訳出力を集め,実
行環境で実行するのに必要となる情報も添えて,実行形プログラムを作り出す。
文字集合
基本ソース文字集合
%!
!
!
の文字は,水平タブ ,垂直タブ ,改ページ文字 及
び 改行文字の四つの制御文字,空白文字,並びに 次に示す
個の図形文字の合計
文字とする。
$
6
"
7
#
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
5
J
K
.
L
+
*
M
/
-
,
N
O
P
Q
R
S
T
U
3
&
(
2
!
)
V
'
W
0
1
X
%
4
Y
Z
国際文字名
0
!
は,他の文字を指名するために用いる。
進四つ組
3
進数字
進数字
進数字
進数字
国際文字名
3
4
進四つ組
4G
進四つ組
進四つ組
国際文字名
4GAAAAAAAA
は,
6
!
での短縮名が
AAAAAAAA
である文字を指名する。国際文字名
4AAAA
は,
6
!
での短縮名が
....AAAA
である文字を指名する。国際文字名の
進値が
.+.
未満 若し くは
.,9
〜
.O9
である場合,又は 国際文字名が指名する文字が基本ソース文字集合の文字である場合,プログラムは不適格
とする。
基本実行文字集合
%!
?
!
及び 基本実行ワイド 文字集合
%!
?
<3-
!
は,それぞれ,基本ソース文字集合の文字すべて,警告文字・後退文字・復帰文字の三つの制御文字,及び す
べてゼロのビットからなる内部表現をもつナル文字
( 基本実行ワイド 文字集合ではナルワイド 文字
<3-
)を含む。それぞれの基本実行文字集合において,それぞれの文字は,非負の互いに異なる値を
もっていなければならない。基本ソース文字集合 及び 基本実行文字集合のそれぞれにおいて,上で掲げた表の
以
降のそれぞれの数字に対応する文字の値は,それの直前にある文字の値より
だけ大きくなければならない。実行文
字集合
?
!
は,基本実行文字集合をその部分集合とする文字集合とする。実行ワイド 文字集合
?
<3-
!
は,基本実行ワイド 文字集合をその部分集合とする文字集合とする。それぞれの実行
文字集合における文字の値は,処理系定義とする。それぞれの実行文字集合は,現地特性の文字を含んでいてもよい。
三つ組表示
他の処理に先立って,
表
に示すとおりに,特定の
文字の列を
個の文字に置き換える。これ
を三つ組表示
1
!A
と呼ぶ。
表
三つ組表示
三つ組
置換え
三つ組
置換え
三つ組
置換え
22%
22
S
22
22'
4
22
T
22
22Z
W
22[
1
22V
X
例
22%
2222
22[22[
2222
は,次に示すとおりに置き換わる。
ST
11
ST
三つ組表示は,
表
に示したものだけとする。三つ組表示を開始する
2
以外の
2
は,置き換えない。
注
ここでの基本ソース文字集合の文字の字形表示は,
文字集合に対応する
の部分文字集合の文字を意図してい
る。しかし,ソースファイルの文字から基本ソース文字集合の文字への変換( 翻訳過程の第
段)は処理系定義となっているから,それ
ぞれの処理系は,基本ソース文字集合の文字がソースファイルの上でどのように表現されるかを文書で示さなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
前処理字句
前処理字句
3
ヘッダ名
識別子
前処理数
文字リテラル
文字列リテラル
前処理記号
これらのいずれにも当てはまらない単独の非空白類文字
それぞれの前処理字句は,字句(
(
)に変換したとき,キーワード,識別子,リテラル,演算子 又は 区切り子の
いずれかになっていなければならない。
前処理字句は,翻訳過程の第
〜
段における最小の字句要素とする。
《前処理字句》は,
《ヘッダ名》,
《識別子》,
《前処
理数》,
《文字リテラル》,
《文字列リテラル》,
《前処理記号》 及び これらに合致しない単一の《非空白類文字》のいずれ
かとする。文字
Z
又は
Y
が最後の分類に入る場合,その動作は,未定義とする。前処理字句は,空白類
<-!1
で区切られる。空白類は,注釈(
)
) 又は 空白類文字
<-!1
( 空白文字,水平タブ,改行文字,
垂直タブ 及び 改ページ文字)とする。空白類は,第
段までの翻訳過程において,
(それが現れていないことも含め )
前処理字句を分離する以上の働きをもつことがある(
(
参照)
。空白類は,ヘッダ名の一部として現れる場合,及び
文字リテラル 又は 文字列リテラルの引用符の中に現れる場合を除いて,前処理字句の部分となることがない。
ソース入力をある文字まで前処理字句に分割し終えた場合,次の前処理字句は,前処理字句のどれかに合致する最
長の文字の列とする。このとき,その先の字句解析が失敗するかど うかは考慮しない。
例
プログラム片
L8
は,
個の前処理字句( 字句としては,浮動小数点リテラルにも整数リテラルにもなら
ない。)として扱う。これを
L
と
8
とに分割すれば,正当な式( 例えば,
8
が
)L
に書き換わるマクロで
あった場合)になる可能性があるにもかかわらず,そうはしない。同様に,プログラム片
L8L
も,
8
がマク
ロ名であるかど うかによらず,
個の前処理字句( 字句としても正当な浮動小数点リテラル )として扱う。
例
プログラム片
)))))
は,
))
))
)
と分割する。これは,
及び
が組込みの型であったとすると,
増加演算子に関する制約に違反した式となる。
))
)
))
と分割すれば,正しい式となるが,そうはし
ない。
#
代替字句
幾つかの演算子 及び 区切り子に対して,代替字句
を設ける。
代替字句は,その綴り
の違いを除いて,言語のすべての面で,正規字句と完全に同等に振る舞う。代替字句は,
表
に示すとおりとする。
表
代替字句
代替
正規
代替
正規
代替
正規
U
00
0%
U
1
1%
3
S
11
W%
3
T
W
[
U3
X
[%
U3U3
0
(
字句
字句
3
識別子
キーワード
リテラル
演算子
注
代替字句には,
二つ組
及び 予約語がある。
二つ組
(
文字の組)という呼称は,必ずしも適切とはいえない。実際,前
処理字句の代替表現の一つに
があるし ,正規字句のいくつかも
文字の組となっている。それにもかかわらず,予約語ではない代
替字句は,
二つ組
と言い習わされている。
注
したがって,
と
とは,その
文字列化
値が相異なり,それぞれソース上での表現となる。しかし ,この違いを除けば,両者を
自在に置き換えることができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
区切り子
《字句》は,
《識別子》,
《キーワード 》,
《リテラル》
,
《演算子》 及び 《区切り子》の
種類とする。空白文字,
水平タブ,垂直タブ,改行文字,改ページ文字 及び 注釈(これらをまとめて空白類と呼ぶ。)は,字句を分離する働
きだけをもつ。
参考
識別子,キーワード,数値リテラル 及び 英字を含んだ代替字句が隣接する場合,その間にそれらを分
離するための空白類が必要となる。
)
注釈
文字
'!
は,注釈を始める。この形の注釈は,
文字
!'
で終わり,入れ子にできない。
文字
''
も,
注釈を始める。この形の注釈は,次の改行文字で終わる。この形の注釈の中に改ページ文字 又は 垂直タブが現れる
場合,その後には,その注釈を終える改行文字までの間に空白類文字以外の文字が現れてはならない。ただし ,その
診断の必要はない。
参考
''
で始まる注釈の中で,
''
,
'!
及び
!'
は,特別の意味をもたず,他の文字と同様に扱われる。同様
に,
'!
で始まる注釈の中で,
''
及び
'!
は,特別な意味をもたない。
ヘッダ名
ヘッダ名
3
文字列
Y
A
文字列
Y
文字列
3
文字
文字列
文字
文字
3
改行文字 及び
を除くソース文字集合の文字
A
文字列
3
A
文字
A
文字列
A
文字
A
文字
3
改行文字 及び
Y
を除くソース文字集合の文字
前処理字句の《ヘッダ名》は,前処理指令
(
(
)の中にだけ現れることができる。それぞれの《ヘッ
ダ名》は,ヘッダ 又は ソースファイル名に変換する。その方法は,処理系定義とする。
文字
Z
若しくは
4
又は 文字の列
'!
若しくは
''
が《
A
文字列》 又は 《
文字列》に現れた場合,及び 文字
Y
が
《
文字列》に現れた場合,その動作は,未定義とする。
*
前処理数
前処理数
3
数字
(
数字
前処理数
数字
前処理数
非数字
前処理数
符号
前処理数
8
符号
前処理数
(
前処理数の字句は,字句要素の形として,整数リテラルの字句(
)及び 浮動小数点リテラルの字句(
)
をすべて包含する。
前処理数は,型も値ももたない。型 及び 値は,整数リテラル 又は 浮動小数点リテラルに変換し( 翻訳過程の第
段,
参照)終えてから付与する。
注
リテラルには,文字リテラル,文字列リテラル 及び 数値リテラルがある。
注
したがって,逆斜線表記に類似する文字列は,未定義の動作を引き起こす。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
識別子
識別子
3
非数字
識別子
非数字
識別子
数字
非数字
3
次のいずれか
国際文字名
P
$
6
"
7
#
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
5
J
K
数字
3
次のいずれか
B
L
+
*
M
/
-
,
N
O
識別子は,その英字 及び 数字の列の長さに制限がない。国際文字名は,その
6
!
での符号化表現が
附
属書
に示すいずれかの範囲にある文字を指名していなければならない。大文字と小文字とを区別する。すべての文
字が意味をもつ。
さらに,識別子の幾つかは,
"##
処理系 及び 標準ライブラリでの用途に予約されている(
)
及び
参照)
ので,別の目的に用いてはならない。ただし ,その診断は,必要としない。
キーワード
表
に示す識別子は,キーワード として予約する( すなわち,翻訳過程の第
段で,常にキー
ワード として扱う。)
。
表
キーワード
$
さらに,演算子 及び 区切り子に対する
表
に示す代替表現(
#
)も,予約する。これらを別の目的に用いてはな
らない。
表
代替表現
注
リンカが拡張文字を受け付けないシステムでは,正当な外部識別子を構成するのに国際文字名を適当に符号化する必要がある。例えば,
国際文字名の
を他では使わない文字 又は 文字列に置き換える。この結果,拡張文字によって長大な外部識別子が生じることがある
が,
では,外部識別子の有効な長さについての翻訳限界を設けていない。
では,外部識別子を含めて,すべての識別子にお
いて大文字と小文字とを別の文字として扱う。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
演算子 及び 区切り子
"##
プログラムの字句表現には,前処理での構文でも使い,字句の演算子 及び 区
切り子に変換しても使う,多くの前処理字句がある。
前処理記号
3
次のいずれか
S
T
3
3
U
U
U3
U3U3
&
3
(((
2
33
(
(!
)
V
!
'
U
W
0
1
X
[
%
)%
V%
!%
'%
U%
W%
0%
1%
%
%
%%
[%
%
%
00
11
))
VV
V!
V
P
P
P
P
それぞれの《前処理記号》は,翻訳過程の第
段で単一の字句に変換する(
参照)
。
リテラル
リテラルには,複数の種類がある。
リテラル
3
整数リテラル
文字リテラル
浮動小数点リテラル
文字列リテラル
真理値リテラル
整数リテラル
整数リテラル
3
進リテラル
整数接尾語
進リテラル
整数接尾語
進リテラル
整数接尾語
進リテラル
3
非零数字
進リテラル
数字
進リテラル
3
.
進リテラル
進数字
進リテラル
3
.
進数字
.5
進数字
進リテラル
進数字
非零数字
3
次のいずれか
L
+
*
M
/
-
,
N
O
進数字
3
次のいずれか
.
L
+
*
M
/
-
,
進数字
3
次のいずれか
.
L
+
*
M
/
-
,
N
O
注
この規格での
……リテラル
という用語は,
で
定数
と読んでいるものを表す。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6
"
7
#
8
9
整数接尾語
3
符号なし接尾語
倍長接尾語
倍長接尾語
符号なし接尾語
符号なし接尾語
3
次のいずれか
G
倍長接尾語
3
次のいずれか
?
整数リテラルは,数字の列からなり,小数点も指数部ももたない。整数リテラルには,その基数を示す先頭部分がつ
くこともあり,その型を指定する接尾語部分がつくこともある。数字列の最初の数字が最上位となる。
進
3
の整数リテラル( 基数が
)は,
.
以外の数字で始まる
進数字の列からなる。
進
の整数リテラル( 基数
が
)は,
.
で始まり
進数字の列が続く
。
進
?3
の整数リテラル( 基数が
)は,
.
又は
.5
で
始まり
進数字の列が続く。
進数字は,
進数字 及び
進値の
L.
から
L/
までを表す英字
〜
及び
6
〜
9
とする。
例
十二は,
L+
,
.LM
又は
.57
と書くことができる。
整数リテラルの型は,その形式,値 及び 接尾語部分によって決める。整数接尾語のつかない
進リテラルの場合,
その型は,
型,
型の順に見ていって,その値が表現可能な最初の型とする。値が
型でも表現で
きない場合,その動作は,未定義とする。整数接尾語のつかない
進リテラル 又は
進リテラルの場合,その型は,
型,
!3
型,
型,
!3
型の順に見ていって,その値が表現可能な最初の型とする。
整数接尾語が
又は
G
だけの場合,その型は,
!3
型,
!3
型の順に見ていって,その値が表
現可能な最初の型とする。整数接尾語が
又は
?
だけの場合,その型は,
型,
!3
型の順に見
ていって,その値が表現可能な最初の型とする。整数接尾語が
,
,
?
,
?
,
G
,
G
,
G?
又は
?G
の場合,その
型は,
!3
型とする。
許容されたど の型でも表現可能でない整数リテラルを含んだ翻訳単位がある場合,そのプログ ラムは,不適格と
する。
文字リテラル
文字リテラル
3
Z
文字列
Z
?
Z
文字列
Z
文字列
3
文字
文字列
文字
文字
3
一重引用符
Z
,逆斜線
4
及び 改行文字を除くソース文字集合の文字
逆斜線表記
国際文字名
逆斜線表記
3
単純逆斜線表記
進逆斜線表記
進逆斜線表記
単純逆斜線表記
3
次のいずれか
注
数字の
及び
は,
進数字でない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
4Z
4Y
42
44
4
4
4
4
4
4
4
進逆斜線表記
3
4
進数字
4
進数字
進数字
4
進数字
進数字
進数字
進逆斜線表記
3
4
進数字
進逆斜線表記
進数字
文字リテラルは,
文字 又は 複数文字を一重引用符でくくる( 例えば ,
ZZ
)。その前に英字
?
を置く( 例えば ,
?ZZ
)こともある。
?
を置かない通常の文字リテラルは,ナロー文字リテラルとも呼ばれる。
個の《
文字》をく
くった通常の文字リテラルは,
型をもち,その《
文字》の実行文字集合での符号数値に等しい値をもつ。
個
以上の《
文字》をくくった通常の文字リテラルを,多文字リテラル
という。多文字リテラ
ルは,
型をもつ。その値は,処理系定義とする。
文字
?
で始まる文字リテラル( 例えば ,
?ZZ
)を,ワイド 文字リテラルという。ワイド 文字リテラルは,
<
型
をもつ。
個の《
文字》をくくったワイド 文字リテラルは,その《
文字》の実行ワイド 文字集合での符号数
値に等しい値をもつ。
個以上の《
文字》をくくったワイド 文字リテラルの値は,処理系定義とする。
いくつかの非図形文字 並びに 一重引用符
Z
,二重引用符
Y
,疑問符
2
及び 逆斜線
4
は,
表
#
のとおりに表現す
ることができる。
表
#
逆斜線表記
名称
記号
表記
改行文字
A??9
4
水平タブ
;
4
垂直タブ
H
4
後退文字
"F
4
復帰文字
7E
4
改ページ文字
99
4
警告文字
"8?
4
逆斜線
4
44
疑問符
2
42
一重引用符
Z
4Z
二重引用符
Y
4Y
進数字
4
進数字
4
二重引用符
Y
及び 疑問符
2
は,それ自身を書いて表すことも,それぞれ《逆斜線表記》
4Y
及び
42
を書いて表
すこともできる。一重引用符
Z
及び 逆斜線
4
は,それぞれ逆斜線表記
4Z
及び
44
を書いて表すほかはない。
《単純
逆斜線表記》の逆斜線に続く文字が
表
#
に示したもの以外である場合,その動作は,未定義とする。
個の単純逆斜
線表記は,
個の文字を表す。
《
進逆斜線表記》
4
は,逆斜線に
個,
個 又は
個の
進数字を続け,その値の文字を指定する。
《
進
逆斜線表記》
4
は,逆斜線に
個以上の
進数字を続け,その値の文字を指定する。
進数字の個数に上限は
ない。
進数字の列 又は
進数字の列は,それぞれ,
進数字 又は
進数字でない文字が現れると終わる。文字
リテラルの値が,
型( 通常のリテラルの場合) 又は
<
型( ワイド 文字リテラルの場合)に対する処理系
定義の範囲に収まっていない場合,その動作は,未定義とする。
《国際文字名》は,それが指名している文字の,実行文字集合での符号数値に変換する。対応する符号数値が存在
しない場合,変換する先の数値は,処理系定義とする。
注
この型は,
バイトには収まらない文字からなる文字集合に用いることを意図している。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
参考
翻訳過程の第
段では,ソース入力に拡張文字が現れると,それを国際文字名に置き換える。したがっ
て,すべての拡張文字は,国際文字名の形で扱うことになる。しかし ,同じ結果をもたらすなら,実際の
処理系は,独自の文字集合を使用して差し支えない。
浮動小数点リテラル
浮動小数点リテラル
3
小数点定数
指数部
浮動小数点接尾語
数字列
指数部
浮動小数点接尾語
小数点定数
3
数字列
(
数字列
数字列
(
指数部
3
符号
数字列
8
符号
数字列
符号
3
次のいずれか
)
V
数字列
3
数字
数字列
数字
浮動小数点接尾語
3
次のいずれか
9
?
浮動小数点リテラルは,整数部,小数点,小数部,
又は
8
,及び 必要に応じて符号を付けた整数の指数部からな
り,必要に応じて型を示す浮動小数点接尾語を置く。整数部 及び 小数部は,それぞれ,
進数字( 基数が
)の列
からなる。整数部 又は 小数部(の一方)は,省くことができる。小数点,又は
若し くは
8
及び それに続く指数
(の一方)は,省くことができる。整数部,省略可能な小数点 及び 省略可能な小数部は,その浮動小数点リテラルの
有効数値部
!>
1
となる。指数部は,もしあれば,有効数値部に乗じる
のべきを表す。乗じた値がその
型の表現可能な大きさの範囲内にある場合,結果は,それが表現可能な値であればその乗じた値とする。そうでなけ
れば ,その乗じた値に最も近い表現可能な値とする。このとき,小さいほうから最も近い値をとるか,大きいほうか
らとるかは,処理系定義とする。浮動小数点リテラルの型は,浮動小数点接尾語を置いて明示してない限り,
3 %
型とする。浮動小数点接尾語が
又は
9
である場合,その型は,
5
型とする。浮動小数点接尾語が
又は
?
であ
る場合,その型は,
3 %
型とする。指数部による
のべきを乗じた値がその型の表現可能な大きさの範囲内
にない場合,そのプログラムは,不適格とする。
文字列リテラル
文字列リテラル
3
Y
!
文字列
Y
?
Y
!
文字列
Y
!
文字列
3
!
文字
!
文字列
!
文字
!
文字
3
二重引用符
Y
,逆斜線
4
及び 改行文字を除くソース文字集合の文字
逆斜線表記
国際文字名
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
文字列リテラルは,文字の列(
で規定する。)を二重引用符でくくる( 例えば,
YE
E
E
Y
)
。その前に応じて英
字
?
を置く( 例えば,
?YE
E
E
Y
)こともある。
?
を置かない通常の文字列リテラルを,ナロー文字列リテラルとも呼ぶ。
通常の文字列リテラルは,
:
個の
の配列
;
型をもち,静的
!
記憶域期間(
)
)をもち,くくら
れた文字の列を初期値としてもつ。ここで,
は文字列の長さ( 後で規定する。)とする。文字
?
で始まる文字列リ
テラル( 例えば ,
?YY
)を,ワイド 文字列リテラルと呼ぶ。ワイド 文字列リテラルは,
:
個の
の配列
;
型をもち,静的記憶域期間(
)
)をもち,くくられた文字の列を初期値としてもつ。
それぞれの文字列リテラルを別々に置く( すなわち,重なりのないオブジェクトとして割り付ける)かど うかは,
処理系定義とする。
翻訳過程の第
段(
)で,隣り合うナロー文字列リテラルど うしを連結し ,隣り合うワイド 文字列リテラルど
うしを連結する。字句のナロー文字列リテラルとワイド 文字列リテラルとが隣り合う場合,その動作は,未定義とす
る。連結した文字列の中の文字は,それぞれ別々に扱う。
例
Y46Y
Y"Y
これを連結した後の文字列は,
個の文字
Z46Z
及び
Z"Z
からなる(
個の
進文字
Z46"Z
とはな
らない。)
。
必要な連結の後,翻訳過程の第
段(
)で,文字列を走査するプログラムがその終わりを検出できるように,す
べての文字列リテラルの終わりに
Z4.Z
を追加する。
文字列リテラルの中の,逆斜線表記 及び 国際文字名は,文字リテラル(
)の中と同じ意味をもつ。ただし,
一重引用符
Z
は,それ自身で表すことも逆斜線表記
4Z
で表すこともできるが,二重引用符
Y
には,
4
を前置しなけ
ればならない。ナロー文字列リテラルの中では,国際文字名が多バイト符号化
%
3
に従って複数の
文字要素に変換されることがある。ワイド 文字列リテラルの長さは,逆斜線表記,国際文字名 及び その他の文字の
総個数に,末尾に付加した
?Z4.Z
の分の
を加えた値とする。ナロー文字列リテラルの長さは,逆斜線表記 及び そ
の他の文字の総個数に,それぞれの国際文字名の多バイト符号化結果のバイト数( 少なくとも
)の総和,及び 末尾
に付加した
Z4.Z
の分の
を加えた値とする。
#
真理値リテラル
真理値リテラル
3
真理値リテラルとは,予約語の
及び
をいう。真理値リテラルの型は,
%
とする。真理値リテラル
は,左辺値をもたない。
基本概念
参考
ここでは,
"##
言語の基本概念を与える。オブジェクトと名前との違いを説明し ,それらが左辺値
0
とどのように関係しているかを説明する。宣言
3
及び 定義
3>
の概念を導入
し,
"##
での型
1
,有効範囲
!1
,結合
I
及び 記憶域期間
!
3
の概念を
提供する。プログラム実行の開始 及び 終了の機構を議論する。最後に,言語の基本型を説明し ,それら
から複合型
1
3
1
を構成する方法を列挙する。
ここでは,言語の特定部分だけに関係する概念は,扱わない。それらは,それぞれ,関係する箇条で扱う。
実体
には,値,オブジェクト,部分オブジェクト,基底クラス部分オブジェクト,配列要素,変数,関数,
関数インスタンス
!
,列挙子,型,クラスメンバ
!!
%
,テンプレート,及び 名前空間が
ある。
名前
は,実体 又は ラベル
%
(
((
及び
(
)を表す識別子(
)の挙用
!
をいう。変数
0
%
は,オブジェクトの宣言が作り出す。変数の名前は,そのオブジェクトを表す。
宣言
3
は,実体を表す名前をプログラムに導入する。ラベルを表す名前は,
文(
((
) 又は ラ
ベル付き文(
(
)がプログラムに導入する。
型,クラス,列挙体 又は テンプレートを表す名前もある。一般に,名前を含んだプログラムを構文解析するには,
名前がこれらの実体を表しているかど うかを調べる必要がある。この処理過程を,名前検索
I 1
(
)と
呼ぶ。
二つの名前は,次のいずれかの場合に等しいとする。
―
それらが同じ文字列からなる識別子である場合
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
―
それらが同じ演算子に対して利用者が多重定義した演算子関数の名前である場合
―
それらが同じ型に対して利用者が定義した変換関数の名前である場合
同じ識別子を複数の翻訳単位で使った場合,それぞれの翻訳単位で指定したその識別子の結合(
#
)にもよるが,
原則として,共通して同じ実体を表す。
宣言 及び 定義
宣言(
)
)は,翻訳単位に名前を導入したり,すでに宣言で導入されている名前を再宣言する。
宣言は,名前の解釈 及び 属性を指定する。
宣言は,次の場合を除いて,定義
3>
という。
―
関数本体(
)を指定せずに関数を宣言している場合
―
?
指定子(
)
) 又は 《結合指定》
(
)#
)を含んでいて,
《初期化子》も《関数本体》
(
)も
含んでいない場合
―
クラス宣言の中で静的データメンバ(
*
)を宣言している場合
―
型定義宣言(
)
),
《
!
宣言》
(
)
) 又は 《
!
指令》
(
)
)の場合
例
次に示す宣言は,
個を除き,すべて定義となる。
&
''
を定義する。
%
L&
''
を定義する。
Q
)&
R
''
及び
を定義する。
F
Q
&
&
R
''
F
F33
及び
F33
を定義する。
5
Q
''
5
を定義する。
&
''
非静的なデータメンバ
を定義する。
&
''
静的なデータメンバ
を宣言する。
5 3
.
Q
R
''
5
のコンストラクタを定義する。
R&
533
%
L&
''
533
を定義する。
Q
R&
''
及び
を定義する。
A
Q
&
R
''
A
及び
A33
を定義する。
AL
%
A&
''
AL
を定義する。
5
5&
''
5
を定義する。
次に示す宣言は,定義とはならない。
&
''
を宣言する。
&
''
を宣言する。
&
''
を宣言する。
F&
''
F
を宣言する。
<&
''
<
を宣言する。
5
5&
''
5
を宣言する。
A33&
''
A33
を宣言する。
参考
状況によって,メンバ関数の,省略時コンストラクタ(
),コピーコンストラクタ(
),代入
演算子(
) 又は デストラクタ(
)を
"##
処理系が暗黙に定義することがある。
例
7
Q
&
''
標準ライブラリの
クラス(
+L(
参照)
R&
Q
7
&
7
%
&
%
&
R
この
7
に対して,処理系が必要な関数を暗黙に定義し ,次に示すのと同等な定義を与える。
7
Q
&
7 3
&
7
70
3
(
Q
R
70
%
70
Q
%
(&
!&
R
X7
Q
R
R&
注
宣言が《結合指定》の中の波括弧でくくった宣言列の内側にあっても,その宣言が定義であるかど うかには影響しない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
参考
クラス名は,
《詳述型指定子》によって暗黙に宣言されることがある(
参照)
。
オブジェクトに対する定義が不完全型(
*
)のオブジェクトをもたらす場合,そのプログラムは,不適格とする。
単一定義規則
翻訳単位は,それぞれの変数,関数,クラス型,列挙型 又は テンプレートに対して,
個以上
の定義を含んでいてはならない。
式は,次のいずれかの場合を除いて,評価対象式
1
0
3
?1!!
という。
―
式が,汎整数定数式が必要な場所に書かれている。
―
式が,
!J
演算子(
#
)の演算対象となっている。
―
式が,
1
3
演算子の演算対象となっており,多相クラス型の左辺値を表していない。
オブジェクト 又は 非多重定義の関数は,その名前が評価対象式に現れていれば,挙用した
!3
という。仮想メン
バ関数は,それが純粋(
)でなければ,挙用したという。多重定義の関数は,評価対象式から参照されて多重定
義解決で選ばれれば ,挙用したという。
参考
この規定は,名前での関数呼出し(
#
),演算子多重定義(
),利用者定義の変換(
),位
置指定
<
式に対する割付け関数(
#
) 及び 省略時でない初期化(
#
)を網羅する。コピーコンス
トラクタは,その呼出しが処理系によって行われても,挙用したことになる。
クラスの割付け関数 又は 解放関数は,評価対象式の中の
<
式によっても挙用したことになる(
#
及び
#
参
照)
。クラスの解放関数は,評価対象式の中の
3
式によっても挙用したことになる(
##
及び
#
参照)
。クラ
スのコピー代入関数は,他のクラスに対して暗黙に定義されたコピー代入関数によっても挙用したことになる(
参照)
。クラスのコンストラクタの挙用は,
#
に規定する。クラスのデストラクタの挙用は,
に規定する。
プログラムには,そのプログラムで挙用したすべてのインラインでない関数 及び すべてのオブジェクトに対して,
ちょうど
個の定義がなければならない。この定義は,そのプログラムの中に直接含まれていてもよいし ,標準ライ
ブラリ 又は 利用者定義のライブラリにあってもよいし ,暗黙に定義されたもの(
,
及び
参照)であっ
てもよい。インライン関数は,挙用した翻訳単位ごとにちょうど
個の定義がなければならない。
クラスは,そのクラス型が完全であることを要求する形で挙用した場合,その挙用している翻訳単位の中にちょう
ど
個の定義がなければならない。
例
次の翻訳単位は,
5
の定義を含んでいないが,適格である。
5&
''
5
を構造型として宣言する。
5!
L&
''
5
をポインタ様式で挙用する。
5!
+&
''
5
をポインタ様式で挙用する。
参考
完全クラス型を要求する文脈については,宣言 及び 式に対する箇条で規定する。
次に示す場合には,クラス型
が完全であることを要求する。
―
型
のオブジェクトを定義する場合(
及び
#
参照)
―
型
のオブジェクトを参照する左辺値に対して,左辺値から右辺値への変換を行う場合(
参照)
―
式を型
に( 明示的にであれ暗黙にであれ )変換する場合(
,
#
,
#)
,
#*
及び
#
参照)
―
!
以外の型をもち,空ポインタ定数でない式を,暗黙の変換(
),動的キャスト(
#)
) 又は 静
的キャスト(
#*
)を用いて,
へのポインタ型 又は
への参照型に変換する場合
―
型
の式にクラスメンバアクセス関数を適用する場合(
##
参照)
―
型
の演算対象に
1
3
演算子(
#
) 又は
!J
演算子(
#
)を適用する場合
―
型
が返却値型 又は 実引数型である関数を定義する(
参照)場合 又は それを呼び出す場合(
#
参照)
―
型
の左辺値を代入する場合(
#)
参照)
クラス型(
*
),列挙型(
)
),外部結合をもつインライン関数(
)
),クラステンプレート(
),静的でない関
数テンプレート(
##
),クラステンプレートの静的なデータメンバ(
#
),クラステンプレート(
#
)
のメンバ関数,及び 指定のないテンプレート仮引数をもったテンプレート特殊化(
)
及び
#
参照)につい
ては,一つのプログラムの中に複数の定義があってもよい。ただし ,それぞれの定義が別々の翻訳単位にあり,しか
も,次に示す要件をすべて満たしていなければならない。
(ここで,複数の翻訳単位に定義がある実体の名前を
と
する。)
―
のそれぞれの定義は,字句の列として同じでなければならない。
―
のそれぞれの定義の中で,名前検索(
)の結果として互いに対応している名前は,
の定義の中で
定義された特定の実体,又は 多重定義の解決(
) 及び 部分テンプレート特殊化(
)の合致の
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
後での同一の実体を参照していなければならない。ただし ,名前が定値
!
オブジェクトを参照して
いて,内部結合 又は 結合なしである場合,そのオブジェクトが,
のすべての定義において同じ汎整数
型 又は 列挙型であり,定数式(
#*
)によって初期化されていて,その値( 番地ではなく)を挙用して
いるだけであり,しかもその値が
のすべての定義において等しいならば,この限りでない。
―
のそれぞれの定義の中で,参照されている多重定義の演算子,変換関数の暗黙の呼出し ,コンストラク
タ,
1
<
関数,及び
1
3
関数は,同じ関数 又は
の定義の中で定義された関数を参
照していなければならない。
―
のそれぞれの定義の中で,関数の( 明示的にであれ暗黙にであれ )呼出しの省略時実引数は,その字句
列が
の定義の中に現れたものとして扱う。すなわち,省略時実引数も,上に示した三つの要件を満たし
ていなければならない( 省略時実引数の部分式に省略時実引数が現れる場合には,それらに対しても再帰
的にこれらの要件を課す。)
。
―
が暗黙に宣言されたコンストラクタ(
)をもつクラスである場合,そのコンストラクタは,挙用し
ているそれぞれの翻訳単位で暗黙に定義されているものとして扱う。このそれぞれの翻訳単位での暗黙の
定義は,基底クラス 又は
のクラスメンバに対する同一のコンストラクタを呼び出さなければならない。
例
''
翻訳単位
L3
5
Q
5 &
5
&
R&
5335
%
.
Q
R
#3
5
Q
R&
#
+&
''
#
は,
5
を呼び出す。
''
翻訳単位
+3
5
Q
5 &
5
&
R&
5335
%
.
%
.
Q
R
#3
5
Q
R&
''
#
は,
5
を呼び出す。
''
#
の暗黙の定義は,単一定義規則に反している。
がテンプレートであり,複数の翻訳単位に定義がある場合,上に示した最後の四つの要件は,テンプレートを囲む
有効範囲の中からそのテンプレート定義で挙用した名前,及び 具現化点での依存する名前に適用する。
がこれら
すべての要件を満たす場合,プログラムは,
の定義が唯一つあるかのように振る舞う。要件を満たしていない場合,
その動作は,未定義とする。
宣言領域 及び 有効範囲
名前を導入する際にプログラム上で対象とする部分を,宣言領域
30
と呼ぶ。宣言領域は,その名前が正当
0
3
である最大の範囲を構成する。ここで,名前が正当であるとは,その
名前を修飾なしで使ってその同じ実体が参照できることをいう。一般に,特定の名前は,必ずしも一連なりにはなっ
ていないプログラム上の部分でだけ正当となる。こうした部分を,有効範囲
!1
と呼ぶ。宣言の有効範囲を規定
するのに,宣言の潜在有効範囲
1
!1
という概念を用いる。宣言の有効範囲は,その潜在有効範囲内に同
じ名前に対する宣言が他になければ ,潜在有効範囲に等しい。他の宣言がある場合,外側の( 包含している)宣言領
域にある宣言の有効範囲は,内側の( 包含される)宣言領域にある宣言の潜在有効範囲を除いたものとなる。
例
%
+M&
Q
%
&
%
M+&
R
識別子
は,
箇所で宣言して( さらに,
箇所で挙用して )いる。最初の
の宣言領域は,この例全体
となる。最初の
の潜在有効範囲は,最初の
の直後から始まり,このプログラムの終わりまで続く。し
注
省略時実引数の名前検索については,
で規定する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
かし ,その( 実際の)有効範囲は,
から
までを除いたものとなる。
の第
の宣言(
&
の直前にある
)の宣言領域は,
から
までの部分となる。しかし,その潜在有効範囲には,
の宣言が含まれない。
の第
の宣言の有効範囲は,その潜在有効範囲に等しい。
宣言は,そこで宣言している名前を,その宣言が現れている有効範囲に導入する。ただし,
3
指定子(
),
《詳述型指定子》
(
) 及び 《
!
指令》
(
)
)によってこの原則が外れることがある。
単一の宣言領域にあって,同じ修飾なしの名前を対象としている複数の宣言については,次の制約がある。
―
すべての宣言が同じ実体を参照しているか,すべての宣言が関数 又は 関数テンプレートを参照している
かでなければならない。
―
その中の一つの宣言だけが,型定義名でないクラス名 又は 列挙体名を宣言していて,しかも,他の宣言
がすべてその同じクラス 又は 列挙子を参照しているか,関数 又は 関数テンプレートを参照しているかで
なければならない。この場合,そのクラス名 又は 列挙体名は,隠ぺい状態(
)
)となる。
参考
名前空間名 又は クラステンプレート名は,宣言領域の中で唯一となっていなければならな
い(
)
及び
参照)
。
参考
これらの制約は,名前を導入する対象の宣言領域に適用する。この宣言領域は,宣言が現れている領域
と必ずしも一致しない。特に,
《詳述型指定子》
(
) 及び 随伴宣言(
)は,それを囲んでいる名
前空間に名前( 可視でなくてもよい。)を導入することがある。こうした場合,これらの制約は,その名
前空間に適用される。局所的な
?
宣言(
#
)は,その宣言のある宣言領域に名前を導入するととも
に,それを囲んでいる名前空間にも名前( 可視でなくてもよい。)を導入することがある。こうした場合,
これらの制約は,この二つの領域ともに適用される。
参考
名前検索については,
に規定する。
宣言位置
名前の宣言位置
1
3
は,原則として,その完全な《宣言子》
(
)の直後であっ
て,その《初期化子》
( もしあれば )の直前をいう。
例
%
L+&
Q
%
&
R
この
番目の
は,自分自身の( 定まらない)値を使って初期化を行っている。
参考
局所的でない名前は,それを隠ぺいする局所的な名前の宣言位置まで可視のままでいる。
例
%
+&
Q
ST&
R
この宣言は,
個の整数からなる配列を宣言する。
列挙子の宣言位置は,その《列挙子定義》の直後とする。
例
%
L+&
Q
Q
%
R&
R
列挙子
は,定数
の値,すなわち
を使って初期化している。
クラスメンバは,その宣言位置の後で,そのクラスの有効範囲内で名前検索することができる。
参考
これは,そのクラスが不完全クラスであっても成り立つ。
例
5
Q
8
Q
$
%
L-
R&
S533$T&
''
B>
R
《詳述型指定子》を使って最初に宣言したクラスの宣言位置は,次のとおりとする。
―
:
《クラスキー》 《識別子》
&;
の形をした《詳述型指定子》の場合,この《詳述型指定子》は,その《識
別子》を,この宣言を含む有効範囲の中でのクラス名として宣言する。
―
:
《クラスキー》 《識別子》
;
の形をした《詳述型指定子》の場合,この《詳述型指定子》が,名前空間
有効範囲で定義される関数の《宣言指定子列》 又は 《仮引数宣言節》の中に現れているとき,この《詳
述型指定子》は,その《識別子》を,その宣言を含む名前空間での《クラス名》として宣言する。そうで
ない場合,随伴宣言でない限り,その《識別子》を,その宣言を含む最小の( クラスでも関数原型でもな
い)有効範囲内に宣言する。
参考
この《詳述型指定子》が列挙体を指している場合,その《識別子》は,すでに宣言してある
《列挙体名》を参照していなければならない。この《詳述型指定子》の《識別子》が《修飾付き
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
識別子》である場合,その《識別子》は,すでに宣言してある《クラス名》 又は 《列挙体名》
を参照していなければならない(
参照)
。
参考
随伴宣言は,それを囲む最小の名前空間のメンバとなっている関数 又は クラスを参照しはするが,その
名前空間に新しい名前を導入しはしない(
)
参照)
。ブロック有効範囲での,関数宣言 及び
?
指定子付きのオブジェクト宣言は,それを囲む名前空間のメンバを参照するだけで,その有効範囲に新し
い名前を導入しはしない。
参考
テンプレートの具現化位置については,
(
で規定する。
局所的な有効範囲
ブロック(
(
)内に宣言した名前は,そのブロックに局所的
であるという。そ
の潜在有効範囲は,その宣言位置(
)から始まり,その宣言領域の終わりまでとする。
関数定義(
)内の関数仮引数名の潜在有効範囲は,その宣言位置から始まる。その関数に《関数監視ブロック》
がある場合,潜在有効範囲は,それに付随する最後のハンド ラの終わりまで広がる。そうでない場合,その関数宣言
の最外側のブロックの終わりまで広がる。仮引数名は,その関数宣言の最外側のブロックでも,
《関数監視ブロック》
に付随するハンド ラの最外側のブロックでも,再宣言してはならない。
例外宣言の中の名前は,そのハンド ラに局所的であるという。この名前は,その処理部の最外側のブロック
で再宣言してはならない。
《
初期化文》の中 並びに
文,
<
文,
文 及び
!<
文の《条件》の中で宣言した名前は,その
文,
<
文,
文 及び
!<
文(その本体となっている文も含む。)に局所的であるという。これらの名前は,その文
の以後の条件 及び その本体となっている文の最外側のブロック(
文にあっては,すべての最外側のブ ロック)で
再宣言してはならない(
(
参照)
。
関数原型有効範囲
関数宣言の中の仮引数の名前,又は 関数定義の宣言子ではない関数宣言子の中の仮引数
の名前( もしあれば )は,関数原型有効範囲をもつ。関数原型有効範囲は,それを囲む最小の関数宣言子の終わりま
で広がる。
関数有効範囲
ラベル(
(
)は,関数有効範囲をもつ。ラベルは,それが宣言してある関数の中であればど
こででも使うことができる。ラベルだけが,関数有効範囲をもつ。
#
名前空間有効範囲
《名前空間定義》の宣言領域は,その《名前空間本体》とする。
《原名前空間名》が表す潜
在有効範囲は,その《原名前空間名》をもった元の宣言領域の中に現れるそれぞれの《名前空間定義》の宣言領域を
連結したものとなる。
《名前空間本体》の中で宣言した実体を,その名前空間のメンバ
%
という。これらの
宣言がその名前空間の宣言領域に導入する名前を,その名前空間のメンバ名という。名前空間メンバ名は,名前空間
有効範囲をもつ。その潜在有効範囲には,その名前空間内の,その メンバの名前の宣言位置以降の部分が含まれる。
メンバの名前空間を指定した《
!
指令》
(
)
)それぞれに対して,そのメンバの潜在有効範囲には,そのメン
バの宣言位置に続くその《
!
指令》の,潜在有効範囲の部分が含まれる。
例
A
Q
&
Q
&
R
&
&
R
Q
%L&
R
''
の潜在有効範囲は,その宣言位置から
''
翻訳単位の終わりまでとなる。
A
Q
''
A33
を多重定義している。
Q
)&
''
は,名前なし名前空間にある。
R
&
''
誤り
3
二重定義
&
''
B>3
関数宣言の重複
''
B>3
A33
の定義
Q
&
''
A33
の呼出し
R
&
''
誤り
3
返却値型が違う。
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
名前空間のメンバは,その名前空間の名前 又は 《
!
指令》の中でそのメンバの名前空間を指名した名前空間の
名前に続く有効範囲解決演算子
33
(
#
)の後でも参照することができる(
参照)
。
翻訳単位の最外側の宣言領域も名前空間となり,大域的名前空間
%
!1
と呼ぶ。大域的名前空間で宣
言された名前は,大域的名前空間有効範囲( 大域的有効範囲ともいう。)をもつ。こうした名前の潜在有効範囲は,そ
の宣言位置(
)に始まり,その宣言領域である翻訳単位の終わりで終わる。大域的名前空間有効範囲をもつ名前
を,大域的
%
であるという。
(
クラス有効範囲
クラスの中で宣言した名前の有効範囲は,次の原則による。
クラスの中で宣言した名前の潜在有効範囲は,その名前の宣言子に続く宣言領域に加えて,そのクラスの
中( 入れ子になったクラスの中も含む。)の,すべての関数本体,省略時実引数 及び 《コンストラクタ初
期化子》を含む。
クラス
の中で挙用している名前
は,その文脈においても,再評価の際の
の完全な有効範囲におい
ても,同じ宣言を参照していなければならない。この規則に対する違反については,診断の必要はない。
クラスの中でそのメンバの宣言を並べ替えると,上の
) 及び
)の下で別の正当なプログラムとなる場
合,プログラムは,不適格とする。診断の必要はない。
メンバ関数の中で宣言した名前は,同じ名前に対する宣言で,その有効範囲がそのメンバ関数のクラスの
終わりまで 又は それ以上に広がっているものを隠ぺいする。
#
クラス定義の終わりまで広がる潜在有効範囲をもつ宣言は,その( クラスの)メンバ定義の宣言領域まで
もその潜在有効範囲に含む。これは,これらのメンバの定義が字句の列としてそのクラスの中にない場合
[静的データメンバ定義,入れ子になったクラス定義,メンバ関数定義(その関数本体も含む。コンストラ
クタ関数(
)の場合は,
《コンストラクタ初期化子》
(
(
)も含む。)など ]にも成り立つ。更に,
その識別子に続くこれらの定義の宣言子の部分すべても,
《仮引数宣言節》 及び すべての省略時実引数を
含めて,その潜在有効範囲に含む。
例
&
Q
%
L
R&
5
Q
ST&
''
誤り
3
は
33
を参照している。
''
再評価すると
533
を参照する。
Q
$ &
R
''
B>3
533
&
Q
%
+
R&
R&
!
&
J
Q
&
''
誤り
3
は
33
を参照している。
''
再評価すると
J33
を参照する。
&
&
R&
<&
#
Q
<
<&
''
誤り
3
並べ替えが生じないにもかかわらず誤り。
R&
クラスメンバの名前は,次の場合にだけ挙用することができる。
―
そのクラス 又は そのクラスから派生したクラス(
)の有効範囲の中
―
そのクラス 又は そのクラスから派生したクラスの型をもつ式を演算対象とする演算子
(
(
##
)の直後
―
そのクラス 又は そのクラスから派生したクラスのオブジェクトへのポインタを演算対象とする演算子
V
(
##
)の直後
―
そのクラス 又は そのクラスから派生したクラスの名前を演算対象とする有効範囲解決演算子
33
(
#
)
の直後
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
名前の隠ぺい
名前は,入れ子になった宣言領域 又は 派生クラスの中で,それと同じ名前を明示的に宣言す
ると隠ぺい
3
することができる(
参照)
。
クラス名(
*
) 又は 列挙体名(
)
)は,同じ有効範囲の中で,同じ名前をオブジェクト,関数 又は 列挙子とし
て宣言すると隠ぺいすることができる。クラス名 又は 列挙体名と,オブジェクト,関数 又は 列挙子とが,同じ有効
範囲の中で( 順序を問わない。)宣言してある場合,そのクラス名 又は 列挙体名は,オブジェクト名,関数名 又は
列挙子名が可視である場所では常に隠ぺいされる。
メンバ関数定義の中で,局所的な名前の宣言は,そのクラスの同じ 名前をもつメンバの宣言を隠ぺいする(
(
参照)
。派生クラス(
)の中でのメンバの宣言は,基底クラスの同じ名前をもつメンバの宣言を隠ぺいする(
参照)
。
名前空間名で修飾した名前の名前検索において,
《
!
指令》によって可視にしようとした宣言も,その《
!
指
令》を含む名前空間の中の同じ名前に対する宣言によって隠ぺいされることがある(
参照)
。
名前は,有効範囲の中にあって隠ぺいされていないとき,可視
0!%
であるという。
名前検索
名前検索の規則は,文法がその文脈での名前の出現を許している限り,すべての名前[《型定義名》
(
)
),
《名前空間名》
(
)
) 及び 《クラス名》
(
*
)を含む。]に対して一様に適用する。名前検索は,名前の
挙用をその名前の宣言(
)に結びつける。名前検索は,原則として,その名前に一意な宣言を結びつける。ただ
し ,その名前が関数名である場合は,複数の宣言を結びつけることがある。このとき,これらの宣言は,多重定義関
数(
)をなすと呼ぶ。多重定義解決(
)は,名前検索が成功してから行う。アクセス規則(
)は,名前
検索 及び 多重定義解決( 適用できるなら )が成功してはじめて適用する。名前検索,関数の多重定義解決( 適用で
きるなら ) 及び アクセス検査がすべて成功してはじめて,その名前の宣言から得た属性を用いて,その後の式の処
理(
#
)を行う。
式が現れた有効範囲の中で修飾なしの名前に対して名前検索を行うことを,
:
式の文脈での名前検索
;
と呼ぶ。
クラス(
*
)の補正クラス名も,名前の隠ぺい 及び 名前検索においては,そのクラスのメンバとして扱う。
参考
結合については,
#
で規定する。有効範囲,宣言位置 及び 名前の隠ぺいについては,
で規定する。
修飾なし名前の名前検索
ここでの名前検索は,いずれも,それぞれの分類ごとに示した順に有効範囲を調べ
ていって宣言を見つけ出す。名前に対する宣言が見つかった時点で,名前検索が終了する。宣言が見つからない場合,
そのプログラムは,不適格とする。
《
!
宣言》があると,その《
!
宣言》を囲む名前空間の中では,その《
!
宣言》で指名した名前空間の
宣言が可視となる(
)
参照)
。ここでの修飾なし名前の名前検索の規定においては,
《
!
宣言》で示した名前空
間の宣言もこの囲む名前空間のメンバとして扱う。
関数呼出しとしての《後置式》で挙用している修飾なし名前の名前検索は,
で規定する。
参考
( 構文解析の中での )式が関数呼出しとしての《後置式》であるかど うかの判定には,通常の名前検索
規則を適用する。
の規則は,式の構文上の解釈には影響しない。
例
&
6
Q
6
0 &
&
6
Q
&
R
R&
式
は,
と同等な《キャスト式》となる。この式が関数呼出しではないことか
ら,実引数依存の名前検索(
)が適用されることはなく,したがって,随伴関数
を見つ
け出すこともない。
関数,クラス 及び 利用者宣言の名前空間の外側にある大域的有効範囲の中で挙用している名前は,その大域的有
効範囲の中で挙用に先立って宣言していなければならない。
関数定義 及び クラス定義の外側にある利用者宣言の名前空間の中で挙用している名前は,その名前空間の中 又は
その名前空間を囲む名前空間の中で挙用に先立って宣言していなければならない。
名前空間
(ここでは,
に大域的有効範囲も含めて考える。)のメンバである関数の《宣言子識別子》の後に現
れる関数定義の中で挙用している名前
は,次のいずれかでなければならない。
注
関数の《宣言子識別子》に続く修飾なしの名前を指す。こうした名前には,
《仮引数宣言節》の中の型 若しくは 省略時実引数の名前,
又は 関数本体の中で挙用している名前がある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
―
挙用に先立って,挙用しているブロックの中 又は それを囲むブロック(
(
)の一つの中で宣言してある。
―
挙用に先立って,名前空間
の中で宣言してある。
―
が入れ子の名前空間である場合,挙用に先立って,
を囲む名前空間の一つの中で宣言してある。
例
6
Q
A
Q
&
R
R
633A33
Q
%
/&
''
の宣言を探すのには次の有効範囲を順に見ていく
''
L
633A33
の最外側のブロック有効範囲,挙用の前だけ
''
+
名前空間
A
の有効範囲
''
*
名前空間
6
の有効範囲
''
M
大域的有効範囲,
633A33
の定義の前だけ
R
クラス
の定義が,メンバ関数の本体の外側 又は 入れ子になったクラス定義の外側にある場合,その定義の中で
挙用している名前
は,次のいずれかを満たしていなければならない。
―
その挙用に先立ってクラス
の中で宣言してあるか,
の基底クラス(
)のメンバとして宣言して
ある。
―
がクラス
に入れ子になっている(
*)
)場合,
の中での
の定義に先立って宣言してあるか,
の
基底クラスのメンバとして宣言してある(この検索は,
を囲んでいるクラスにも最内側のものから順に
適用する。
―
が局所クラス(
*
)である場合,又は
が局所クラスに入れ子になったクラスである場合,クラス
の定義に先立って,その定義を囲んでいるブロックで宣言してある。
―
が名前空間
のメンバである場合,
が名前空間
のメンバであるクラスに入れ子になったクラスで
ある場合,又は 名前空間
のメンバである関数に局所クラスの中で,
が局所クラス 又は 入れ子になっ
たクラスである場合,クラス
の定義に先立って,名前空間
の中 又は
を囲む名前空間の一つの中
で宣言してある。
例
@
Q
"
Q
R&
R
A
Q
J
3
@33"
Q
5
Q
ST&
R&
R&
R
''
に対する宣言を探しに,次の範囲を順に調べる
''
L
クラス
A33J335
の中,
の挙用の前だけ
''
+
クラス
A33J
の中,
A33J335
の定義の前だけ
''
*
A33J
の基底クラスである
@33"
の中
''
M
名前空間
A
の中,
A33J
の定義の前だけ
''
/
大域的有効範囲,
A
の定義の前だけ
参考
随伴宣言が導入したクラス 又は 関数の宣言を検索する場合,囲んでいる最内側の名前空間有効範囲の
外側にある有効範囲は,対象としない(
)
参照)
。
参考
クラスの定義の中で挙用している名前に対する制約は,
(
で規定する。入れ子になったクラスの定
義の中で挙用している名前に対する制約は,
*)
で規定する。局所クラスの定義の中で挙用している名前
に対する制約は,
*
で規定する。
クラス
のメンバ関数(
*
)の定義の中で,関数の《宣言子識別子》の後に挙用している名前
は,次のい
ずれかを満たしていなければならない。
注
これは,その《クラス名》に続く修飾のない名前を指す。こうした名前の挙用は,
《基底節》の中 又は クラス定義の中で生じる。
注
この検索は,
の定義が
の定義の中に入れ子になっている場合にも,
の定義が,
の定義を囲む名前空間の中に現れている場合
(
参照)にも,適用する。
注
これは,例えば,次の中に現れる修飾なしの名前を指す。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
―
名前
は,その挙用に先立って,挙用しているブロック(
(
)の中 又は それを囲んでいるブロックの一
つの中で,宣言してある。
―
名前
は,クラス
のメンバ 又は
の基底クラスのメンバとなっている(
参照)
。
―
がクラス
に入れ子になったクラス(
*)
)である場合,名前
は,クラス
又は
の基底クラスの
メンバとなっている(この検索は,
を囲んでいるクラスにも,内側から順に適用する。
―
が局所クラス(
*
) 又は 局所クラスに入れ子になったクラスである場合,名前
は,クラス
の定
義に先立って,それを囲んでいるブロックの中で宣言してある。
―
が名前空間
のメンバである場合,
が名前空間
のメンバであるクラスに入れ子になったクラスで
ある場合,又は 名前空間
のメンバである関数に局所クラスの中で,
が局所クラス 又は 入れ子になっ
たクラスである場合,名前
は,そのメンバ関数の定義に先立って,名前空間
の中 又は
を囲む名
前空間の一つの中で宣言してある。
例
"
Q
R&
@
Q
A
Q
5
3
"
Q
&
R&
R
R
@33A33533
Q
%
L-&
R
''
の宣言を探して,次の有効範囲を順に調べる。
''
L
@33A33533
の最外側のブロック有効範囲,
の挙用の前だけ
''
+
クラス
@33A335
の有効範囲
''
*
@33A335
の基底クラス
"
の有効範囲
''
M
名前空間
@33A
の有効範囲
''
/
名前空間
@
の有効範囲
''
-
大域的有効範囲,
@33A33533
の定義の前だけ
参考
メンバ関数の定義の中で挙用する名前に対する制約は,
*
及び
*
で規定する。入れ子になったクラ
スの有効範囲の中で挙用する名前に対する制約は,
*)
で規定する。局所的クラスの定義の中で挙用する
名前に対する制約は,
*
で規定する。
随伴性を与えるクラスの中の,インライン関数としての随伴関数(
)の定義の中で挙用している名前に対する
名前検索は,メンバ関数の定義の中での名前に対する名前検索と同様に行う。随伴関数が随伴性を与えるクラスの中
で定義してあるのでなければ ,その随伴関数の定義の中での名前に対する名前検索は,名前空間のメンバ関数の定義
の中での名前に対する名前検索と同様に行う。
メンバ関数を指す随伴宣言の中で,関数宣言子の中で挙用していて《テンプレート識別子》の《テンプレート実引
数》の一部となっていない名前は,まず,そのメンバ関数のクラスの中で検索する。そこで見つからない場合,又は
その名前が《テンプレート識別子》の《テンプレート実引数》の一部である場合,検索は,随伴性を与えているクラ
スの定義の中での修飾のない名前に対する検索と同様に行う。
例
6
Q
6&
L6 &
+ &
R&
"
Q
"&
633L6 &
''
仮引数の型は
6336
となる。
633+" &
''
仮引数の型は
"33"
となる。
R&
―
《仮引数宣言節》の中の型 又は 省略時実引数式の中
―
その関数本体の中
―
コンストラクタ定義の中の《メンバ初期化子》の式の中
注
メンバ関数がクラス
の定義の中で定義してあるか,メンバ関数がクラス
の定義を囲む名前空間有効範囲の中で定義してある場合
に,この名前検索を適用する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
関数の《仮引数宣言節》の中の省略時実引数(
(
)として挙用している名前,又は コンストラクタに対する《メ
ンバ初期化子》
(
(
)の《式》の中で挙用している名前 に対する名前検索の途中では,その関数の仮引数名は可
視とし ,その関数宣言を囲むブロック,クラス 又は 名前空間の有効範囲で宣言してある実体の名前を隠ぺいする。
参考
省略時実引数の中で挙用している名前に対する制約は,
(
で規定する。
《コンストラクタ初期化子》
の中で挙用している名前に対する制約は,
(
で規定する。
クラス
の静的データメンバの定義の中で( その静的メンバの《修飾付き識別子》の直後に )挙用している名前
(
*
)は,その名前が
のメンバ関数の中で挙用してある場合と同様の検索を行う。
参考
静的データメンバの定義の中で挙用している名前に対する制約は,
*
で規定する。
《関数監視ブロック》のハンド ラ(
#
)の中で挙用している名前は,その名前がその関数定義の最外側のブロッ
クで挙用してある場合と同様の検索を行う。特に,その関数の仮引数名は,
《例外宣言》の中,及び その《関数監視ブ
ロック》のハンド ラの最外側のブロックの中で再宣言してはならない。関数定義の最外側のブロックの中で宣言して
ある名前は,
《関数監視ブロック》のハンド ラの有効範囲に対する検索の対象とはしない。
参考
しかし ,その関数の仮引数名は,検索の対象となる。
参考
テンプレート定義の中での名前検索は,
(
で規定する。
実引数依存の名前検索
関数呼出し(
#
)の《後置式》として挙用している修飾のない名前に対する名前
検索では,通常の修飾のない名前に対する名前検索(
)で対象としない名前空間も対象とすることがあり,可視
でない名前空間有効範囲の随伴関数宣言(
)も見つけ出すことがある。検索方法に対するこれらの変更は,その
実引数の型(テンプレートの《テンプレート実引数》では,その《テンプレート実引数》の名前空間)に依存する。
関数呼出しの実引数の型
に対して,それぞれ,
個以上の関連名前空間 及び
個以上の関連クラスを定める。全
体の関連名前空間 及び 関連クラスは,すべての実引数の型に対するもの( 及び テンプレートのそれぞれの《テンプ
レート実引数》の名前空間)の総体として定める。このとき,型を指定するのに用いている 型定義名 及び 《
!
宣
言》は,考慮しない。
に対する関連名前空間 及び 関連クラスは,次のとおりとする。
―
が基本型の場合,関連名前空間 及び 関連クラスは,なしとする。
―
がクラス型( 共用型を含む。)の場合,関連クラスは,そのクラスそのもの 並びに その直接 及び 間接
の基底クラスとする。関連名前空間は,関連クラスが定義してあるそれぞれの名前空間とする。
―
が列挙型の場合,関連名前空間は,その型が定義してある名前空間とする。関連クラスは,
がクラス
メンバのときそのメンバのクラスとし,それ以外のとき,なしとする。
―
が型
へのポインタ 又は 型
の配列の場合,
の関連名前空間 及び 関連クラスは,それぞれ,
の
関連名前空間 及び
の関連クラスとする。
―
が関数型の場合,関連名前空間 及び 関連クラスは,それぞれ,その関数の実引数型 及び 返却値型の,
関連名前空間 及び 関連クラスの総体とする。
―
がクラス
のメンバ関数へのポインタの場合,
の関連名前空間 及び 関連クラスは,その関数の実引
数型 及び 返却値型の,関連名前空間 及び 関連クラス 並びに
の関連名前空間 及び 関連クラスの総体
とする。
―
がクラス
のデータメンバへのポインタの場合,
の関連名前空間 及び 関連クラスは,それぞれ,そ
のデータメンバの型 及び
の,関連名前空間 及び 関連クラスとする。
―
が《テンプレート識別子》の場合,関連名前空間 及び 関連クラスは,そのテンプレートが定義してあ
る名前空間,メンバテンプレートであるときはそのメンバテンプレートのクラス,テンプレートの型仮引
数( テンプレートのテンプレート仮引数は除く。)に対する《テンプレート実引数》の型それぞれの関連
名前空間 及び 関連クラス,並びに テンプレートの《テンプレート実引数》として挙用しているメンバテ
ンプレートが定義してあるクラスの総体とする。
参考
テンプレートの実引数であっても型実引数でなければ ,関連名前空間には関与しない。
更に,その実引数が,多重定義された関数 及び/又は 関数テンプレートの集合に対する,名前 又は アドレ スの場
合,その実引数の関連名前空間 及び 関連クラスは,その集合の個々の構成員の関連名前空間 及び 関連クラス(すな
わち,関数 又は 関数テンプレートが定義されている名前空間 並びに 非依存の仮引数の型 及び 返却値の型の関連名
前空間)の総体とする。
修飾のない名前に対する通常の名前検索でクラスのメンバ関数が見つかった場合,関連名前空間 及び 関連クラス
は,用いない。そうでない場合,関数名に対する名前検索では,通常の名前検索で見つかった宣言に加えて,関連名
前空間 及び 関連クラスの中で見つかる宣言も合わせて検索の対象とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
参考
実引数の型の関連名前空間 及び 関連クラスには,通常の修飾なし名前の名前検索ですでに検索対象と
した名前空間 及び クラスを含む。
例
AF
Q
Q
R&
&
R
AF33
&
Q
&
''
B>3
AF33
を呼び出す。
R
関連名前空間の中での検索は,その関連名前空間が修飾子(
)となっている場合の名前検索と同様に行う。
ただし ,次の特例をおく。
―
その関連名前空間の中の《
!
指令》は,すべて無視する。
―
関連名前空間の中で宣言してある名前空間有効範囲の随伴関数は,通常の名前検索において可視でないと
しても,それぞれの関連名前空間の中で可視として扱う(
参照)
。
修飾付き名前の名前検索
クラスメンバ 又は 名前空間メンバの名前は,そのクラス 又は 名前空間を指名す
る《入れ子名前指定子》に続く有効範囲解決演算子
33
(
#
)の直後でも参照することができる。有効範囲解決演算
子
33
に先立つ名前についての名前検索では,オブジェクト,関数 及び 列挙子の名前を無視する。見つかった名前
が《クラス名》
(
*
) 又は 《名前空間名》
(
)
)でない場合,そのプログラムは,不適格とする。
例
6
Q
3
&
R&
Q
6&
633
%
M+&
''
B>
6
&
''
不適格
3
6
は,型の名前でない。
R
参考
入れ子になったクラス(
*)
) 又は 入れ子になった名前空間のメンバを参照するのに,多重に修飾の付
いた名前( 例えば ,
AL33AL33A*33
)を使うことができる。
宣言の《宣言子識別子》が《修飾付き識別子》である場合,その宣言の中では,その《修飾付き識別子》の前で挙
用してある名前に対してはその宣言を囲む名前空間有効範囲の中で名前検索を行い,その《修飾付き識別子》の後で
挙用してある名前に対してはそのメンバのクラス 又は 名前空間の有効範囲の中で名前検索を行う。
例
5
Q
R&
7
Q
5
Q
R&
%
/.&
5
ST&
R&
5
733ST&
''
不適格
3
''
335
733S733
T&
に等価であり
''
7335
733S733
T&
には等価でない
単項の有効範囲解決演算子
33
(
#
)を前置した名前に対しては,挙用してある翻訳単位での大域的有効範囲の
中で名前検索を行う。この名前は,大域的有効範囲の中で宣言してあるか,その大域的有効範囲の中で《
!
指令》
によって可視となっている宣言による名前であるかのいずれかでなければならない(
参照)
。この
33
を使う
ことで,その識別子自身が隠ぺい
)
されていても,大域的な名前を参照することが可能となる。
《入れ子名前指定子》を含む《擬似デストラクタ名》
(
#
)の《型名》に対しては,その《入れ子名前指定子》
が指定している有効範囲の中で型の名前を検索する。次に示す形の《修飾付き識別子》で示してある《クラス名》に
対しては,その《入れ子名前指定子》が指定している有効範囲の中で型の名前を検索する。
33
入れ子名前指定子
X
クラス名
ただし ,
《入れ子名前指定子》が名前空間有効範囲を指定するものに限る。
33
入れ子名前指定子
クラス名
33
X
クラス名
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
7
Q
<&
R&
<L
<+&
!
&
!
&
V733<33X< &
''
<
は,
7
の有効範囲の中で検索する。
V<L33X<+ &
''
<+
は,この後置式の有効範囲の中で検索する。
6
Q
X6 &
R&
6
6"&
Q
6"
!&
V6"33X6" &
''
6
のデストラクタに対する明示的な呼出しとなる。
R
参考
演算子
(
及び
V
の直後での名前検索については,
#
に規定する。
クラスメンバ
《修飾付き識別子》の《入れ子名前指定子》がクラスを指名している場合,その《入れ子
名前指定子》の後ろに指定してある名前は,原則として,そのクラスの有効範囲の中で検索する(
参照)
。この
検索の結果として,その名前は,そのクラスの中 又は そのクラスの基底クラス(
)の一つの中の,
個以上のメ
ンバを表していなければならない。
参考
クラスメンバは,その潜在有効範囲の中であればいつでも,
《修飾付き識別子》を使うことによって参照
することができる(
(
参照)
。
ただし ,次の特例をおく。
―
デストラクタ名の名前検索は,
に規定する。
―
《演算子関数識別子》の《変換型識別子》に対しては,クラスの有効範囲の中とともに,その《後置式》
全体が位置している文脈でも検索を行う。この両者の検索の結果として,同じ型を参照していなければな
らない。
―
《テンプレート識別子》の《テンプレート実引数》に対しては,その《後置式》全体が位置している文脈
での検索を行う。
《入れ子名前指定子》がクラス
を指し ,
《入れ子名前指定子》の後に指定された名前が
の中を名前検索したと
きに
の補整クラスであった場合(
*
参照),その名前は,クラス
のコンストラクタの名前として扱われる。こ
ういうコンストラクタの名前は,クラス定義の外に書かれるコンストラクタ定義の《宣言子識別子》の中でしか使っ
てはならない。
例
6
Q
6 &
R&
"3
6
Q
" &
R&
6336
Q
R
"33"
Q
R
"336
&
''
型
6
のオブジェクト
6336
&
''
エラー
3
6336
は型名でない。
クラスメンバが,入れ子の宣言領域での同じ名前 又は 派生クラスのメンバの同じ名前によって隠ぺいされている
場合でも,そのクラスの名前に演算子
33
を添えた修飾を付ければ ,そのクラスメンバが名前検索で見つかる。
名前空間メンバ
《修飾付き識別子》の《入れ子名前指定子》が名前空間を指名している場合,その《入
れ子名前指定子》の後ろに指定してある名前は,その名前空間の有効範囲の中で検索する。ただし,
《テンプレート識
別子》の《テンプレート実引数》に対しては,その《後置式》全体が位置する文脈の中で名前検索を行う。
《修飾付き識別子》を
533
(
5
は利用者宣言の名前空間) 又は
33
(
5
は大域名前空間)とするとき,
5
の中の
の宣言のすべて,並びに
5
及び その挙用している名前空間の中に置いた《
!
指令》で指名している名前空間の推
移的閉包の中の
の宣言のすべてからなる集合を
とおく。ただし ,
《
!
指令》による推移的閉包を求めるに当
たっては,
5
を含めて,
の
個以上の宣言を含んでいる名前空間での《
!
宣言》を無視する。名前検索の途中で
は,どの名前空間も
度だけ検索する。
が空集合となる場合,そのプログラムは,不適格とする。そうではなくて,
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
がただ
個の要素をもつ場合,及び その参照の文脈が《
!
宣言》である(
)
参照)場合は,
を
に結び
つく宣言の集合とする。上のいずれでもない場合,その
の挙用が
の中からただ一つの宣言を選べるものでない
とき,そのプログラムは,不適格とする。
例
&
J
&
&
K
&
6
J&
&
&
&
"
K&
&
&
6"
6&
"&
&
6"33 &
''
は
6"
で直接宣言してある。
''
したがって,
は
6"33
となり,
6"33
が選ばれる。
6"33L &
''
は
6"
で直接宣言してはないので,
''
再帰的に規則を
6
と
"
とに適用する。
''
名前空間
J
は検索の対象とならず,
''
J33
が見つかることはない。
''
は
633
"33
となり,
''
多重定義解決によって
633
が選ばれる。
6"33ZZ &
''
上と同様にして多重定義解決によって
"33
が選ばれる。
6"33))&
''
は
6"
で直接宣言してはないし,
''
6
でも
"
でも宣言してないので
''
再帰的に規則を
J
と
K
とに適用する。
''
は
となり,このプログラムは不適格となる。
6"33))&
''
は
6"
で直接宣言してはないので,
''
再帰的に規則を
6
と
"
とに適用する。
''
は
633
"33
となり,この挙用はあいまいである。
''
ので,このプログラムは不適格となる。
6"33L-(N &
''
は
6"
で直接宣言してはないし,
''
6
と
"
とでも直接宣言してはないので,
''
再帰的に規則を
J
と
K
とに適用する。
''
は
J33
K33
となり,
''
多重定義解決によって
K33
が選ばれる。
同じ宣言が
度以上見つかるのは,
(ただ一つの宣言が見つかっていることなので )あいまいといわない。
例
6
&
"
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6&
7
6&
"7
"&
7&
"733))&
''
B>3
は
633
633
となる。
#
633&
"#
"&
#&
"#33))&
''
B>3
は
633
633
となる。
参照してある名前空間は高々
度しか検索しないから,次のプログラムは,適格となる。
例
"
&
6
"&
&
"
6&
633))&
''
B>3
は
6
で直接宣言してある。
は
633
となる。
"33))&
''
B>3
6
と
"
を(
L
度) 検索する。
は
633
となる。
633))&
''
B>3
6
と
"
を(
L
度) 検索する。
は
"33
となる。
"33))&
''
B>3
は
"
で直接宣言してある。
は
"33
となる。
修飾付きの名前空間メンバの名前検索の途中で,その名前のメンバの宣言が
個以上見つかり,その一つが《クラ
ス名》 又は 《列挙体名》を宣言し ,他の宣言が同じオブジェクト 又は 同じ列挙子を宣言するか,関数を導入してい
る場合,その《型名》でない名前が《クラス名》 又は 《列挙体名》を隠ぺいするのは,それらの宣言がすべて同一
の名前空間にある場合だけとする。
例
6
Q
Q
R&
&
&
R
"
Q
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
Q
R&
R
7
Q
6&
"&
%
733&
''
B>3
633
(
型)
%
733&
''
あいまい
3
633
なのか
"33
なのか不明。
R
名前空間メンバの宣言において,その《宣言子識別子》が次の形の《修飾付き識別子》である場合,その《修飾な
し識別子》は,その《入れ子名前指定子》が指定する名前空間のメンバの名前でなければならない。
入れ子名前指定子
修飾なし識別子
例
6
Q
"
Q
L &
R
"&
R
633L
Q
R
''
不適格
3
L
は
6
のメンバでない。
こうした名前空間メンバの宣言にあっても,その《入れ子名前指定子》の前半部分を《
!
指令》に頼ることは差
し支えない。
例
6
Q
"
Q
L &
R
R
7
Q
#
Q
L &
R
R
6&
733#&
"33L
Q
R
''
B>3
633"33L
を宣言する。
詳述型指定子
《詳述型指定子》を用いることによって,すでに宣言してある《クラス名》 又は 《列挙体
名》が型以外の識別子によって隠ぺいされている(
)
参照)場合であっても,その《クラス名》 又は 《列挙体
名》を参照することができる。このとき,
《詳述型指定子》の中の《クラス名》 又は 《列挙体名》は,単に《識別子》
であっても《修飾付き識別子》であってもよい。
《詳述型指定子》の中の名前が単に《識別子》である場合,その《詳述型指定子》全体が,次の形で現れているの
でなければ,その《識別子》は,
に従って検索する。
クラス種別
識別子
&
ただし ,その際に,宣言してある型以外の名前は,無視する。 この名前検索によって,
《型定義名》が見つかった場
合,その《詳述型指定子》を含むプログラムは,不適格とする。 その《詳述型指定子》が《列挙体名》を参照してい
て,この検索によってすでに宣言してある《列挙体名》が見つからない場合,その《詳述型指定子》を含むプログラ
ムは,不適格とする。その《詳述型指定子》が《クラス名》を参照していて,この検索によってすでに宣言してある
《クラス名》が見つからない場合,又は その《詳述型指定子》全体が,次の形で現れている場合,その《詳述型指定
子》は,その《クラス名》を導入する宣言となる(
参照)
。
クラス種別
識別子
&
《詳述型指定子》の中の名前が《修飾付き識別子》である場合,その名前は,その修飾に応じて
に従って検
索する。ただし,その際に,すでに宣言してある型以外の名前は,無視する。この名前検索で《型定義名》が見つかっ
た場合,そのプログラムは,不適格とする。この名前検索で,すでに宣言してある《クラス名》 又は 《列挙体名》が
見つかった場合,そのプログラムは,不適格とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
A
Q
A!
A&
''
B>3
大域的有効範囲での
A
を参照している。
#!
#&
''
B>3
型
#
を大域的有効範囲に宣言し ,
''
メンバ
#
を宣言している。
R&
#
Q
A!
A&
''
B>3
大域的有効範囲での
A
を参照している。
33:&
''
誤り
3
:
は宣言されていない。
''
修飾のある型は導入できない
,(L(/(*
参照
。
:&
''
B>3
大域的有効範囲での( まだ )宣言されていない
''
:
を参照している。
R&
"
Q
#&
''
B>3
入れ子の
#
を宣言する。
33#!
#&
''
B>3
33#
を参照している。
"33#!
#&
''
B>3
入れ子の
#
を参照している。
33#&
''
B>3
大域的な
#
は随伴である。
#&
''
B>3
入れ子の
#
は随伴である。
#
Q
'!
(((
!'
R&
''
入れ子の
#
の定義である。
R&
#&
''
B>3
大域的有効範囲での
#
の再宣言
33#&
''
誤り
3
修飾のある型は導入できない
,(L(/(*
参照
。
"33#&
''
誤り
3
修飾のある型は導入できない
,(L(/(*
参照
。
"33#&
''
誤り
3
#
は宣言されていない。
"33#!
"&
''
B>3
入れ子の
#
を参照している。
#
クラスメンバアクセス
クラスメンバアクセス式(
##
)において,字句
(
又は
V
に続く《識別子》の直
後に
がある場合は,まずその識別子を検索し ,その
がテンプレート実引数並び(
)の始まりであるのか比
較演算子であるのかを決定する。この識別子は,まず,そのオブジェクト式のクラスの中で検索する。そこで見つか
らない場合,その《後置式》全体の文脈の中で検索を行う。その結果として,クラス 又は 関数テンプレートの名前
が見つからなければならない。オブジェクト式のクラスの中で検索してテンプレートが見つかった場合,続けてその
《後置式》全体の文脈の中で検索を行う。その結果に応じて,次のとおりとする。
―
名前が見つからなければ ,オブジェクト式のクラスの中での検索で見つかった名前を結果とする。
―
名前が見つかってもそれがクラステンプレートでなければ ,オブジェクト式のクラスの中での検索で見つ
かった名前を結果とする。
―
クラステンプレートの名前が見つかれば ,そのクラステンプレートの名前を結果とする。ただし ,その名
前は,オブジェクト式のクラスの中での検索で見つかったものと同じ実体を参照していなければならない。
そうなっていない場合,そのプログラムは,不適格とする。
クラスメンバアクセス(
##
)の《識別子式》が《修飾なし識別子》であり,そのオブジェクト式の型がクラス型
( 又は クラス型
へのポインタ)である場合,その《修飾なし識別子》は,クラス
の有効範囲で検索する。オ
ブジェクト式の型がスカラ型へのポインタである場合,その《修飾なし識別子》は,その《後置式》全体の文脈で検
索する。
その《修飾なし識別子》が
:X
《型名》
;
であり,そのオブジェクト式の型がクラス型
(又は クラス型
へのポイ
ンタ)である場合,その《型名》は,その《後置式》全体の文脈,及び クラス
の有効範囲で検索する。その結果,
その《型名》は,
《クラス名》を参照していなければならない。両方の検索でともに見つかった場合,その名前は,と
もに同じ クラス型を参照していなければならない。オブジェクト式の型がスカラ型である場合,その《型名》は,そ
の《後置式》全体の文脈で検索する。
クラスメンバアクセス(
##
)の《識別子式》が,次の形で始まっている場合,
(字句
(
又は
V
に続く)その《ク
ラス名前空間名》は,その《後置式》全体の文脈,及び オブジェクト式のクラスの有効範囲の両者で検索する。
クラス名前空間名
33
(((
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
オブジェクト式のクラスの有効範囲での検索でだけ名前が見つかった場合,その名前は,
《クラス名》を参照していな
ければならない。その《後置式》全体の文脈での検索でだけ名前が見つかった場合,その名前は,
《クラス名》 又は
《名前空間名》を参照していなければならない。両者で名前が見つかった場合,その名前は,同じ 実体を参照してい
なければならない。
参考
《クラス名前空間名》の検索の結果は,その《修飾付き識別子》が表す実体がオブジェクト式のクラス
型のメンバであって,しかも
に従ってあいまいでなく定まるのであれば ,一意的にオブジェクト式
のクラス型の基底クラスとなっている必要はない。
例
6
Q
&
R&
"3
6
Q
R&
73
"
Q
R&
#3
"
Q
R&
83
7
#
Q
R&
93
6
Q
R&
Q
8
&
("33
%
.&
''
B>3
8
の中では
633
しかない。
9
&
(633
%
L&
''
B>3
633
は
9
のメンバである。
R
《修飾付き識別子》が次の形で始まっている場合,その《クラス名前空間名》は,大域的有効範囲の中で,
《クラス
名》 又は 《名前空間名》として検索する。
33
クラス名前空間名
33
(((
《入れ子名前指定子》がクラスの《テンプレート識別子》
(
)である場合,その《テンプレート実引数》は,そ
の《後置式》全体が現れている文脈の中で評価する。
その《識別子式》が《変換関数識別子》である場合,その《変換型識別子》は,その《後置式》全体が現れている
文脈の中でも,そのオブジェクト式のクラス( 又は ポインタ式が指しているクラス)の文脈の中でも,同じ型を表し
ていなければならない。
(
指令 及び 名前空間別名
《
!
指令》 又は 《名前空間別名定義》の中の《名前空間名》を検索す
る場合は,
《名前空間名》だけを検索対象とする。
#
プログラム 及び 結合
プログラムは,
個以上の翻訳単位(
)を結合して構成する。
《翻訳単位》は,宣言
の列から成る。
翻訳単位
3
宣言列
名前は,他の有効範囲の中の宣言が導入した名前と同じ オブジェクト,参照,関数,型,テンプレート,名前空間
又は 値を表し うる場合,結合
I
をもつという。
―
名前が外部結合
?
I
をもつ場合,その名前が表す実体は,他の翻訳単位の有効範囲 又は 同
じ翻訳単位の他の有効範囲の名前で参照することができる。
―
名前が内部結合
I
をもつ場合,その名前が表す実体は,同じ翻訳単位の他の有効範囲の名
前で参照することができる。
―
名前が結合をもたない
I
場合,その名前が表す実体は,他の有効範囲の名前では参照すること
ができない。
名前空間有効範囲をもつ名前(
#
)は,次に示す場合,内部結合をもつ。
―
と明示的に宣言してある オブジェクト,参照,関数 又は 関数テンプレートの名前である場合
―
と明示的に宣言してある オブジェクト 又は 参照の名前であって,
と明示的に宣言してな
いし ,それまでに外部結合をもつとも宣言してない場合
―
名前なし共用体のデータメンバの名前である場合
名前空間有効範囲をもつ名前は,次に示す場合,外部結合をもつ。
―
オブジェクト 又は 参照の名前であって,内部結合をもたない場合
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
―
関数の名前であって,内部結合をもたない場合
―
名前付きクラス(
*
)の名前である場合 又は 型定義宣言で定義している名前なし クラスの名前である場
合[そのクラスは,結合を示すための型定義名をもつ(
)
参照)
。]
―
名前付き列挙体(
)
)の名前である場合 又は 型定義宣言で定義している名前なし列挙体の名前である場
合[その列挙体は,結合を示すための型定義名をもつ(
)
参照)
。]
―
外部結合をもった列挙体に属している列挙子の名前である場合
―
テンプレートの名前である場合[ただし ,関数テンプレートの名前であって内部結合をもつ名前は除く
(
参照)
。]
―
名前空間(
)
)の名前である場合(ただし ,名前なし名前空間の内部で宣言してあるときは除く。)
更に,クラス有効範囲の,メンバ関数,静的なデータメンバ,クラス 又は 列挙体の名前は,そのクラスの名前が
外部結合をもっている場合,外部結合をもつ。
大域的有効範囲で宣言してある関数の名前,及び 大域的有効範囲の
?
宣言で宣言してあるオブジェクトの名
前は,結合をもつ。その名前と同じ名前 及び 同じ型をもった結合をもつ実体の宣言が可視である場合(ただし ,囲
んでいる最内側の名前空間有効範囲の外側で宣言してある実体は除外する。),その大域的有効範囲での宣言は,それ
と同じ実体を宣言し ,それまでの宣言の結合を受け継ぐ。このとき,合致する実体が
個以上あるなら,そのプログ
ラムは,不適格とする。合致する実体が
個もなければ ,その大域的有効範囲の実体は,外部結合をもつ。
例
&
%
.&
''L3
Q
&
''
内部結合
&
''+3
は結合をもたない。
Q
&
''
内部結合
&
''*3
外部結合
R
R
このプログラムには,名前
をもったオブジェクトが
個ある。
―
大域的有効範囲の宣言( 行
''L
)での,内部結合をもつオブジェクト
―
行
''+
の宣言での,結合をもたない自動記憶域期間のオブジェクト。
―
行
''*
の宣言での,外部結合をもった静的記憶域期間をもつオブジェクト。
結合をもった実体のブロック有効範囲の宣言の中に他の宣言が見つからない場合,その実体は,囲んでいる最内側
の名前空間のメンバとする。しかし ,そのような宣言は,名前空間有効範囲にそのメンバ名を導入するのではない。
例
5
Q
Q
&
''
誤り
3
がまだ宣言されていない。
&
''
は名前空間
5
のメンバとなる。
R
Q
&
''
誤り
3
がまだ宣言されていない。
R
Q
'!
(((
!'
R
''
533
の定義
R
Q
'!
(((
!'
R
''
無関係な
の他の宣言
これらの規則に当てはまらない名前は,結合をもたない。更に,局所的な有効範囲(
)で宣言してある名前
は,特に規定したものを除いて,結合をもたない。
結合をもたない名前( 特に,局所的な有効範囲(
)で宣言したクラス 又は 列挙体の名前)は,結合をもった
実体を宣言するために挙用してはならない。宣言に型定義名が挙用してある場合,その型定義名が参照している型名
の結合を,その宣言の結合とする。
例
Q
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
6
Q
&
R&
''
結合なし 。
6
&
''
不適格
6
"&
"
&
''
不適格
R
この結果として,結合をもたない名前は,テンプレートの実引数として挙用することができない(
参照)
。
別の有効範囲で宣言してある二つの名前が同一である場合(
参照),その二つの名前は,次の条件を満たすとき,
同じ オブジェクト,参照,関数,型,列挙子,テンプレート 又は 名前空間を表す。
―
両者がともに外部結合をもつ場合 又は 両者ともに内部結合をもち,同じ翻訳単位の中で宣言してある場合
―
両者がともに同じ名前空間 又は 同じ クラス( 継承によらない)のメンバを参照している場合
―
両者がともに関数を表し ,その関数の型が多重定義という意味で一致している場合
―
両者がともに関数テンプレートを表し ,その呼出し情報(
##
)が同じである場合
型のすべての調整[その過程の中で,型定義名(
)
)は,その定義で置き換える。]の後で,対象とするオブジェ
クト 又は 関数を参照しているすべての宣言で指定している型は,同一でなければならない。ただし ,配列オブジェ
クトの宣言にあっては,その主配列の上限(
)の有無に違いがあってもよい。型の同一性に関するこの規則に対
する違反は,診断情報を必要としない。
参考
"##
ではない宣言へは,
《結合指定》を用いることによって結合することができる(
)#
参照)
。
(
開始 及び 終了
(
関数
プログラムには,大域的な関数
が含まれていなければならない。この関数から,プログラ
ムの実行が始まる。自立処理系でのプログラムに関数
を定義する必要があるかど うかは,処理系定義とする。
参考
自立処理系においては,プログラムの開始 及び 終了は,処理系定義となる。開始では,少なくとも,静
的記憶域期間をもつ名前空間有効範囲のオブジェクトに対するコンストラクタを実行する。終了では,少
なくとも,静的記憶域期間をもつオブジェクトに対するデストラクタを実行する。
処理系は,関数
をあらかじめ定義しておいてはならない。関数
は,多重定義してはならない。その返却
値の型は,
とする。これを除いて,関数
の型は,処理系定義とする。処理系は,次に示すど ちらの形での
関数
の定義も受理できなければならない。
Q
'!
(
(
(
!'
R
!
ST
Q
'!
(
(
(
!'
R
後者の形の場合,
は,そのプ ログラムを環境の下で実行する際にプログ ラムに渡された実引数の個数とする。
が
でない場合,
S.T
から
SVLT
には,それぞれの実引数を表している
)+'4/
(ナル文字で終
端した多バイト文字列(
)
)
)の最初の文字を指すポインタが入っていなければならない。とくに,
S.T
は,そのプログラムを駆動するのに使われた名前を表す
)+'4/
の最初の文字を指すポインタ 又は
;
;
を指すポイ
ンタでなければならない。
の値は,非負でなければならない。
ST
の値は,
でなければならない。
参考
更に追加の引数を設ける場合は,
の後におくのが望ましい。
関数
は,プログラムの中で挙用してはならない(
参照)
。
の結合(
#
)は,処理系定義とする。
を
又は
と宣言してある場合,そのプログラムは,不適格とする。これらを除いては,名前
を予
約しない。
例
( 大域的有効範囲でない)他の名前空間の中の実体に
という名前を付けてよいのと同様に,メンバ
関数,クラス 及び 列挙体に
という名前を付けてもよい。
(
)に宣言してある次の関数は,実行中のブロックを抜け出すことなくプログラムの実行を終了さ
せるので,自動記憶域期間をもつオブジェクトを解体しない(
参照)
。
&
静的記憶域期間をもつオブジェクトの解体中に
が呼び出された場合,その動作は,未定義とする。
の中の
文は,関数
を抜け出し(その際に自動記憶域期間をもったすべてのオブジェクトを解体
し ),その返却値を実引数として
を呼び出す働きをもつ。
文に出会うことなく制御が関数
の終わり
に達した場合,次の文の実行と同じ働きをもつ。
.&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
(
非局所オブジェクト の初期化
静的記憶域期間をもつオブジェクト(
)
)は,他の初期化に先立ってゼロ
初期化を行う(
#
参照)
。ゼロ初期化 及び 定数式による初期化を総称して,静的初期化
!
J
と呼
ぶ。これら以外の初期化を,動的初期化
3
J
と呼ぶ。静的記憶域期間をもち定数式(
#*
)での
初期化をもつ
"
互換型
2*
1
(
*
)のオブジェクトは,動的初期化に先立って,その定数式による初期化を
行う。翻訳単位の中の名前空間で定義してあるオブジェクトは,静的記憶域期間をもち動的初期化を行う場合,その
翻訳単位の中で定義が現れている順に初期化を行う。
参考
集成体のメンバの初期化の順序は,
#
で規定する。局所的な静的オブジェクトの初期化は,
()
で規
定する。
処理系は,名前空間有効範囲の静的記憶域期間をもつオブジェクトの初期化について,静的に行うことが要件となっ
ていない場合でも,それらを静的初期化として行ってもよい。ただし,次の条件を満たす場合に限る。
―
その初期化を動的に行ったとき,名前空間有効範囲の静的記憶域期間をもつ他のオブジェクトがその初期
化以前にもっている値を変えることがない。
―
その初期化を静的に行ったとき,静的な初期化が要件となっているものを除き,すべてのオブジェクトを
動的に初期化したとして得られるのと同じ値を設定することになる。
参考
この結果として,オブジェクト
L
の初期化が,名前空間有効範囲の静的記憶域期間をもったオブジェ
クト
+
を参照していて,その
+
が潜在的に動的初期化を必要とし ,同じ翻訳単位の後ろで定義して
あるとすると,
L
の初期化に使われる値が,完全に初期化し 終えた
+
の値となる(
+
の初期化
が静的に行われた場合)か,単にゼロ初期化だけした
+
の値となるかは,処理系定義となる。
例
Q
L(.&
R
&
+
%
&
''
未規定
3
''
.(.
に静的初期化してもよいし ,
''
L(.
に動的初期化してもよい。
%
&
''
L(.
に静的初期化してもよい。
名前空間有効範囲のオブジェクトの動的初期化を,
の最初の文の前に行うかど うかは,処理系定義とする。た
だし,
の最初の文よりも後に行う場合でも,そのオブジェクトと同じ翻訳単位の中で定義してある関数 又は オ
ブジェクトの最初の挙用以前に行わなければならない。
例
''
V
9
L
V
Y(Y
Y(Y
"
&
6336
Q
(G &
R
''
V
9
+
V
Y(Y
6
&
''
V
9
*
V
Y(Y
Y(Y
6
&
"
&
Q
(G &
(G &
R
又は
の初期化が
に入る前に行われているか,
の中での
の最初の挙用まで後回しになっ
ているかは,処理系定義となる。とくに,
が
に入る前に初期化される場合,
が
の初期化で使わ
れる前,つまり
6336
が呼び出される前に
の初期化が行われているとは限らない。一方,
の初期化が
の最初の文以降まで後回しになる場合,
の初期化は,
6336
での挙用の前に行われる。
注
名前空間有効範囲で定義してあるオブジェクトに副作用をもった初期化がある場合,プログラムでそのオブジェクトが挙用してないと
しても,その初期化を行わなければならない(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
局所的でない静的なオブジェクトのコンストラクタ 又は デストラクタが,受取りのない例外を送出して終わった
場合,その結果として,
(
(
)を呼び出す。
(
終了
静的記憶域期間をもった初期化済みのオブジェクト( 大域的有効範囲 又は 名前空間有効範囲で宣言し
てあるもの )に対しては,
からの戻り 又は
(
)の呼出しの結果として,そのデストラクタ(
)を
呼び出す。これらのオブジェクトは,そのコンストラクタ 又は 動的初期化が完了した順序の逆順に解体する。静的
初期化を行ったオブジェクトの解体は,そのオブジェクトに動的初期化を行うとした場合と同じ順に行う。配列型 又
は クラス型のオブジェクトの部分オブジェクトは,その構築の際に初期化を行った静的記憶域期間をもった局所オブ
ジェクトを解体するよりも前に,解体する。
すでに解体された静的記憶域期間をもつ局所オブジェクトが関数の中にあって,静的記憶域期間をもつオブジェク
トの解体の最中にその関数が呼び出された場合,制御がその解体された局所オブジェクトの定義を通過すれば ,その
プログラムの動作は,未定義とする。
の呼出しが生じたとき
(
,
参照)で登録した関数がある場合,それらの関数は,プロ
グラムの終了処理の中で呼び出す。この関数の呼出しについては,次の要件をおく。
―
関数の登録以前に初期化を行った静的記憶域期間をもつオブジェクトの解体は,登録した関数の呼出しが
完了してから行わなければならない。
―
関数の登録後に構築した静的記憶域期間をもつオブジェクトの解体は,登録した関数の呼出しまでに行わ
なければならない。
―
その構築中に関数の登録を行ったオブジェクトの解体は,そのオブジェクトが属している総体オブジェク
トの解体とともに,登録した関数の呼出しまでに行わなければならない。
で定義してある次の関数は,自動記憶域期間 又は 静的記憶域期間をもつオブジェクトのデストラクタ
を実行することもなく,
で登録した関数を呼び出すこともなしに,プログラムを終了させる。
&
)
記憶域期間
オブジェクトの特性の一つに記憶域期間
!
3
がある。記憶域期間は,そのオブジェ
クトを収める記憶域に対する最小保証生存期間を示す。記憶域期間は,そのオブジェクトを生成するのに用いた構文
規則によって,次のいずれかとなる。
―
静的記憶域期間
―
自動記憶域期間
―
動的記憶域期間
宣言(
)で導入され,処理系によって暗黙に生成(
)されたオブジェクトの記憶域期間は,静的記憶域期間
又は 自動記憶域期間となる。
(
#
)で作ったオブジェクトの記憶域期間は,動的記憶域期間となる。
記憶域種別指定子
及び
は,記憶域期間の種別決定に関与する。
記憶域期間の種別を,そのまま参照にも当てはめる。参照の生存期間とは,その参照を保持する記憶域の記憶域期
間のこととする。
)
静的記憶域期間
動的記憶域期間をもたず局所的でもないオブジェクトは,すべて静的記憶域期間をもつ。静
的記憶域期間をもつオブジェクトの記憶域は,そのプ ログラムの実行期間中,維持し続けなければならない(
(
及び
(
参照)
。
副作用のある初期化 又は デストラクタをもった静的記憶域期間のオブジェクトは,そのオブジェクトが使われて
いないとわかる場合であっても,プログラムから取り除いてはならない。ただし,それがクラスオブジェクト 又は そ
のコピーの場合には,
に従って取り除くことができる。
キーワード
を使うことによって,静的記憶域期間をもった局所変数を宣言することができる。
参考
局所静的変数の初期化は,
()
で規定する。局所静的変数の解体は,
(
で規定する。
キーワード
をクラス定義の中でクラスデータメンバに指定すると,そのデータメンバの記憶域期間は,静
的記憶域期間となる。
)
自動記憶域期間
又は
と明示宣言してある局所オブジェクト 及び
とも
とも
明示宣言していない局所オブジェクトは,自動記憶域期間をもつ。それらのオブジェクトの記憶域は,それを作成し
たブロックを抜け出るまで,維持し続けなければならない。
参考
それらのオブジェクトの初期化 及び 解体は,
()
で規定している。
副作用のある 初期化 又は デストラクタをもった自動記憶域期間の名前付きオブジェクトは,そのブロックの終わ
りに達するまで解体してはならない。そのオブジェクトが使われていないとわかる場合であっても,最適化処理でプ
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ログラムから取り除いてはならない。ただし ,それがクラスオブジェクト 又は そのコピーの場合には,
に従っ
て取り除くことができる。
)
動的記憶域期間
オブジェクトは,プログラムの実行(
*
)中に,
《
<
式》
(
#
)を使って動的に生成する
ことができ,
《
3
式》
(
##
)を使って動的に解体することができる。
"##
処理系は,動的記憶域をアクセスし管
理する手段として,大域的な割付け関数
及び
ST
並びに 大域的な解放関数
及び
ST
を提供する。
標準ライブラリは,それらの大域的な割付け関数 及び 大域的な解放関数に対する省略時定義を提供する。大域的
な割付け関数 及び 大域的解放関数の中には,上書き可能なものもある(
参照)
。上書き可能な割付け関数 又
は 解放関数に対して,
"##
プログラムは,その定義を高々一つ与えることができる。その関数定義は,標準ライブ
ラリが提供する省略時定義版を置き換える(
)
参照)
。プログラムのそれぞれの翻訳単位での大域的有効範囲
に,次に示す割付け関数 及び 解放関数(
)が暗黙に宣言される。
!
33$P
33P
&
!
ST33$P
33P
&
!
&
ST!
&
これらの暗黙宣言は,
,
ST
,
及び
ST
という関数
名だけを導入する。
参考
これらの暗黙宣言は,
,
33
及び
33$
という名前を導入しないし,それらの
名前を宣言するために標準ライブラリが使う他のいかなる名前も導入しない。したがって,
という
ヘッダを取り込まないで,
《
<
式》,
《
3
式》 又は 関数呼出しにおいて,それらの関数を使っても,
そのプログラムが不適格となることがない。しかし ,
,
33
又は
33$
を参照す
る場合には,適切なヘッダを取り込んでその名前を宣言しない限り,そのプログラムは不適格となる。
割付け関数 及び 解放関数は,いずれもクラスごとに宣言することができるし ,定義することができる(
#
参照)
。
"##
プログラム( 標準
"##
ライブラリを含む。)で定義するすべての割付け関数 及び 解放関数は,
)
及
び
)
の意味規則に合致していなければならない。
)
割付け関数
割付け関数は,クラスメンバ関数 又は 大域的関数でなければならない。割付け関数が大域的
有効範囲でない名前空間有効範囲で宣言されている場合,又は 割付け関数が大域的有効範囲で
と宣言してあ
る場合,そのプログラムは不適格とする。割付け関数の返却値の型は,
!
でなければならない。第
仮引数の型
は,
$
(
)でなければならない。第
仮引数は,附随する省略時実引数(
(
)をもっていてはならない。
第
仮引数の値は,割付け要求の大きさと解釈される。割付け関数は,関数テンプレートであってもよい。そのよう
なテンプレートでは,その返却値の型 及び 第
仮引数を,上に規定したとおりに宣言しなければならない( すなわ
ち,テンプレート仮引数の型を,返却値の型 及び 第
仮引数の型に使ってはならない。)
。テンプレート割付け関数
は,二つ以上の仮引数をもっていなければならない。
割付け関数は,要求しただけの記憶域を割り付けようとする。成功した場合,記憶域ブロックの先頭アドレスを返
す。その記憶域ブロックの大きさは,要求分以上でなければならない。割付け関数から戻った時点での記憶域の内容
は,何であってもよい。同じ割付け関数を何度か呼び出したときに割り付けられる記憶域の順序,連続性 及び 初期
値については,未規定とする。割付け関数が結果として返すポインタは,次のことができるように境界調整されなけ
ればならない。すなわち,そのポインタが,任意の完全オブジェクト型に変換することができ,かつ,
(その記憶域が
対応する解放関数呼出しによって明示的に解放されるまでの間)割り付けた記憶域内のオブジェクト 又は 配列をア
クセスするのに使うことができるように,境界調整されなければならない。要求された領域の大きさがゼロの場合で
あっても,その要求は成功しないことがある。成功した場合,返却する値は,空ポインタ値(
)としてはならず,
以前に返却した値
L
と異なっていなければならない。ただし ,その値
L
がすでに
に渡されてい
る場合,
L
と同じであってもよい。大きさゼロの要求に対する返却値のポインタを参照はずしした結果は,処理系依
存とする。
割付け関数は,記憶域割付けに失敗した場合,その時点で設定されている
(
)があればそれ
を呼び出すことができる。
参考
プログラムで用意した割付け関数は,関数
(
)を使って,その時点で設定さ
れている
のアドレスを得ることができる。
注
この規定は,
を実装するのに,実質的に
又は
を呼び出すだけでよいようにすることを意図し
ている。
では,大きさゼロの要求に対し空ポインタではない値を返すことが
言語と異なる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
空の《例外指定》
(
#
),すなわち
という指定で宣言してある割付け関数は,記憶域割付けに失敗した場合,
空ポインタを返さなければならない。その他の割付け関数は,記憶域割付けに失敗した場合,クラス
33
(
) 又は その派生クラスの例外を送出して失敗を示すだけとし ,それ以外のことをしてはならない。
大域的な割付け関数が呼び出されるのは,次のいずれかの場合に限る。
―
<
式(
#
)の結果としての呼出し
―
関数呼出し構文規則(
#
)を使った直接的な呼出し
―
呼び出した標準
"##
ライブラリ中の関数の呼出しからの間接的な呼出し
参考
特に,次に示す記憶域の割付けのために,大域的な割付け関数を呼び出すことはない。
―
静的記憶域期間(
)
)をもったオブジェクトの記憶域
―
型
(
#
)のオブジェクトの記憶域
―
<
式(
#
)で送出されたオブジェクトのコピーのための記憶域
)
解放関数
解放関数は,クラスメンバ関数 又は 大域的な関数でなければならない。解放関数が大域的有効
範囲ではない名前空間有効範囲で宣言してある場合,又は 大域的有効範囲で静的に宣言してある場合,プログラムは
不適格とする。
各解放関数は,
を返さなければならず,その第
仮引数の型は,
!
でなければならない。解放関数には,
二つ以上の仮引数があってもよい。クラス
の中に,仮引数が一つだけで名前が
というメンバ
解放関数がある場合,その関数が通常の( 位置指定なしの )解放関数となる。そのような
がクラ
ス
に宣言されていず,仮引数が二つだけの
というメンバ解放関数が宣言されており,その第
仮引数の型が
33$
(
)である場合,その関数が通常の解放関数となる。同様に,クラス
の中に,仮
引数が一つだけで名前が
ST
というメンバ解放関数がある場合,その関数が通常の( 位置指定なし
の )解放関数となる。そのような
ST
をクラス
に宣言していず,仮引数が二つだけの
ST
というメンバ解放関数が宣言されており,その第
仮引数の型が
33$
である場合,その関数が通
常の解放関数となる。解放関数は,関数テンプレートのインスタンスの一つとしてもよい。第
仮引数 及び 返却値
のど ちらも,テンプレート仮引数に依存していてはならない。
参考
すなわち,解放関数テンプレートは,その第
仮引数の型を
!
とし ,返却値の型を (ここで規定
したとおり)
としなければならない。
解放関数テンプレートは,二つ以上の関数仮引数をもたなければならない。具現化された関数は,その呼出し情報に
よらず,通常の解放関数になることはない。
標準ライブラリで提供される解放関数の中には,それに供給される第
実引数の値が空ポインタ値であってもよ
いものもある。その場合,その解放関数の呼出しの効果はない。そうでない場合,標準ライブラリの中の
!
に供給される第
実引数の値は,標準ライブ ラリの中の
$
又は
$
33
0
のいずれかを先行して呼び 出したときの返却値の一つでなければならず,
標準ライブ ラリの中の
ST!
に供給され る値は,標準ライブ ラリの中の
ST
$
又は
ST
$
33
0
のいずれかを先行して呼び出したときの返却
値の一つでなければならない。
標準ライブラリで提供される解放関数に設定した実引数が空ポインタ値(
)でない場合,その解放関数は,そ
の実引数のポインタが指す記憶域を解放し,解放された記憶域中のいずれかの部分を指しているすべてのポインタを
無効にする。無効になったポインタの値を使った場合,その効果( 解放関数に渡すことを含めて)は,未定義とする。
)
部分オブジェクト の記憶域期間
メンバの部分オブジェクト,基底クラスの部分オブジェクト 及び 配列要素
の記憶域期間は,それらを含む総体オブジェクトの記憶域期間と同じとする(
参照)
。
オブジェクト の生存期間
オブジェクトの実行時特性の一つとして,オブジェクトの生存期間がある。型
の
オブジェクトの生存期間の始まりは,型
の大きさをもち適切に境界調整された記憶域が,獲得された時点とする。
ただし ,
が自明でないコンストラクタ(
)をもつクラス型の場合には,コンストラクタ呼出しが完了していな
ければならない。型
のオブジェクトの生存期間の終わりは,次の時点とする。
―
が自明でないデストラクタ(
)をもつ場合には,そのデストラクタの呼出しが始まった時点
―
そうでない場合には,オブジェクトが占有している記憶域が,再利用された時点 又は 解放された時点
注
処理系によっては,システムが生成する実行時障害となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
参考
配列オブジェクト 又は
"
互換型のオブジェクト(
*
)の生存期間は,適切な大きさに境界調整された
記憶域が獲得されたときに始まり,オブジェクト 又は 配列が占有している記憶域が再利用 又は 解放され
たときに終わる。基底部分オブジェクト 及び メンバ部分オブジェクトの生存期間は,
(
で規定する。
この規格全体を通して,オブジェクトの特性についての規定は,生存期間中のオブジェクトに対してだけ適用さ
れる。
参考
特に,オブジェクトの生存期間の開始前 及び 終了後については,
(
及び
)
で規定するとおり,
オブジェクトの使用に多くの制約がつく。構築中 及び 解体中のオブジェクトの動作は,オブジェクトの生
存期間が開始しまだ終了していないオブジェクトの動作と同じでないかもしれない。構築の段階 及び 解
体の段階におけるオブジェクトの動作は,
(
及び
)
で規定する。
オブジェクトが占有する記憶域を再使用することによって,又は 自明でないデストラクタをもっているクラス型の
オブジェクトの場合にそのデストラクタを明示的に呼び出すことによって,プログラムは,どんなオブジェクトもそ
の生存期間が終了したとみなしてよい。自明でないデストラクタをもつクラス型のオブジェクトの場合,プログラム
は,オブジェクトの占有する記憶域が再使用 又は 解放される前に,そのデストラクタを明示的に呼び出さなくても
よい。しかし ,デストラクタの明示的呼出しがなく,かつ記憶域を解放するための 《
3
式》
(
##
)が使われな
い場合,そのデストラクタは暗黙に呼び出されないので,そのデストラクタによって生じる副作用に依存するプログ
ラムの動作は,未定義とする。
オブジェクトの生存期間が開始していず,オブジェクトが占有する予定の記憶域の割付けが済んでいる場合
,
又は オブジェクトの生存期間は終了しているが,オブジェクトの占有する記憶域が再使用されていないか 又は 解放
されていない場合,オブジェクトがその後に作られる記憶域 又は それがあった記憶域の場所を指すポインタを使っ
てもよいが,制限付きでしか使えない。そのようなポインタが,割り付けられた記憶域(
)
)を指しており,そ
のポインタが型
!
であるように使われる場合は,適格とする。そのようなポインタの参照をはずすことができる
が,その左辺値は,次に示すように制限付きでしか使えない。オブジェクトが自明でないデストラクタのクラス型に
なるか 又は そうであった場合であって,そのポインタが 《
3
式》の演算対象に使われた場合,プログラムの動
作は,未定義とする。オブジェクトが
"
互換でないクラス型になるか 又は なっていた場合であって,次のいずれか
の条件を満たす場合,プログラムの動作は,未定義とする。
―
そのポインタを使って,静的でないデータメンバをアクセスしている,又は そのオブジェクトの静的でな
いメンバ関数を呼び出している。
―
そのポインタを,ある基底クラスの型へのポインタに暗黙に変換している(
参照)
。
―
そのポインタを,静的キャスト(
#*
)の演算対象に使っている(ただし ,
!
に変換している場合,
及び
!
に変換して最終的に
!
又は
!
に変換している場合は,除く。)
。
―
そのポインタを動的キャスト(
#)
)の演算対象に使っている。
例
"
Q
&
&
X" &
R&
#L
3
"
Q
&
R&
#+
3
"
Q
&
R&
"33
Q
#+&
''
記憶域の再使用,
!
の生存期間の終了
&
''
動作未定義
(((
%
''
B>3
自体は,正当なメモリを指している。
R
Q
!
%
$#L
)
$#+ &
"!
%
#L&
V &
0&
''
B>3
は,正しいメモリを指している。
!
%
&
''
B>3
は,正しいメモリを指している。
V &
''
動作は未定義。
!
の生存期間は終わっている。
R
注
例えば,
互換でないクラス型の大域的なオブジェクトの構築の前(
参照)
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
同様に,次の時点では,元のオブジェクトを参照する左辺値は,制限付きでしか使えない。
―
オブジェクトの生存期間が始まる前であるが,そのオブジェクトが占有する記憶域が割り付けられた後の
時点
―
オブジェクトの生存期間が終了した後であるが,そのオブジェクトが占有する記憶域が再使用されるか 又
は 解放される前の時点
そのような左辺値が,割り付けられた記憶域(
)
)を参照している場合,その値に依存しない左辺値の特性を使
うことは,適格とする。左辺値から右辺値への変換(
)が,そのような左辺値に適用された場合,そのプログラ
ムの動作は未定義とする。元のオブジェクトが
"
互換でないクラス型になるか 又は 既になっていて,次のいずれか
の場合,そのプログラムの動作は未定義とする。
―
オブジェクトの静的でないデータメンバへアクセスするために,又は 静的でないメンバ関数を呼び出すた
めに,その左辺値を使っている。
―
その左辺値が,基底クラス型の参照のために暗黙に変換される(
参照)
。
―
その左辺値を,静的キャスト(
#*
)の演算対象に使っている(ただし,変換が結局は
0
又は
0
になる場合は除く。)
。
―
その左辺値を,動的キャスト(
#)
)の演算対象 又は
の演算対象に使っている。
オブジェクトの生存期間が終了した後であって,オブジェクトの占有記憶域を再使用したか 又は 元のオブジェク
トが解放される前に占有していた記憶域に新しいオブジェクトを作った場合,元のオブジェクトを指していたポイン
タ,元のオブジェクトを参照していた参照 及び 元のオブジェクトの名前は,自動的に新オブジェクトを参照するこ
とになる。さらに,それらのポインタ,参照 及び 名前は,新オブジェクトの生存期間が開始した後では,次の条件
をすべて満たす場合には,新オブジェクトの操作に使うことができる。
―
新オブジェクトの記憶域が,元のオブジェクトの占有記憶域に完全に重なっている。
―
新オブジェクトの型が,元のオブジェクトの型と( 最上位の
0
修飾子は除いて)同じである。
―
元のオブジェクトの型が定値修飾されていず,クラス型である場合には,定値修飾された型 又は 参照型
の非静的データメンバを含んでいない。
―
元のオブジェクトが,型
の最派生したオブジェクト(
)であり,新オブジェクトが型
の最派生し
たオブジェクトである( すなわち,基底クラスの部分オブジェクトではない。)
。
例
7
Q
&
&
70
%
70
&
R&
70
733%
70
Q
[%
0
Q
VX7
&
''
!
の生存期間が終了する。
7
&
''
型
7
の新オブジェクトを作る。
&
''
適格
R
!&
R
7
L&
7
+&
L
%
+&
''
適格
L(
&
''
適格
3
L
は,型
7
の新オブジェクトを参照する。
プログラムが,静的記憶域期間(
)
) 又は 自動記憶域期間(
)
)をもつ型
のオブジェクトの生存期間を
終了させ,かつ,
が自明でないデストラクタをもつ場合
,プログラムは,デストラクタを暗黙に呼び出すとき
に,元の型のオブジェクトが記憶域の同じ場所を占有していることを保証しなければならない。保証できない場合,
そのプログラムの動作は未定義とする。これは,例外発生によってブロックから出る場合にもあてはまる。
例
Q
R&
"
Q
X"
&
R&
注
すなわち,自動記憶域期間のオブジェクトならブロックから出る時点で,静的記憶域期間のオブジェクトならプログラムから出る時点
で,デストラクタを暗黙に呼び出すオブジェクトとする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
Q
"
&
0
&
R
''
ブロック出口での動作は未定義。
静的記憶域期間 若しくは 自動記憶域期間の定値オブジェクトが占有する記憶域,又は そのような定値オブジェク
トがその生存期間終了前に占有していた記憶域に,新オブジェクトを生成した場合,そのプログラムの動作は未定義
とする。
例
"
Q
"
&
X"
&
R&
"
&
Q
(X"
&
0
"&
''
動作は未定義。
R
*
型
参考
ここでは,型の表現に関して処理系に課せられる要件を示す。型には,基本型 及び 複合型の二つがあ
る。型は,オブジェクト(
),参照(
) 又は 関数(
#
)を記述する。
"
互換型
の任意のオブジェクト( 基底クラスの部分オブジェクトを除く。)では,そのオブジェクトが型
の値
を正しく保持しているか否かにかかわらず,そのオブジェクトを構成するバイトは,
型 又は
!3
型
の配列にコピーすることができる。
型 又は
!3
型の配列の内容をそのオブジェクトに逆にコピー
した場合,元のオブジェクトは,その元の値にならなければならない。
例
A
$
SAT&
&
''
は元の値に初期化される。
0
A
&
''
二つの
の呼出しの間で,
''
は変更され うる。
0
A
&
''
この時点で,
のスカラ型の部分
''
オブジェクトは,元の値をもつ。
"
互換型
では,
への二つのポ インタが異なるオブジェクト
及び
を指していて(ここで,
及
び
は基底クラスの部分オブジェクトではないとする。),
の値をライブラリ関数
を使って
に
コピーした場合,
は,
と同じ値をもたなければならない。
例
!
L&
!
+&
''
+
は,初期化されたオブジェクトを指すとする。
L
+
$
&
''
この時点で,
!L
の
7
互換型の部分オブジェクトの
''
それぞれは,対応する
!+
の部分オブジェクトと
''
同じ値になる。
型
のオブジェクト表現
%
=
1!
とは,
を
$
とするとき,型
のオブジェクトが占
める
個の
!3
型のオブジェクトの列のこととする。オブジェクトの値表現
0
1!
とは,
型
の値を保持するビットの集合のこととする。
"
互換の型の場合,値を決めるオブジェクト表現におけるビット
集合が値表現になる。ここで,個々の値とは,処理系で定義している値集合の中のある離散的要素とする。
オブジェクト型には,境界調整の要求(
*
及び
*
参照)がある。総体オブジェクト型は,バイト数を表わ
す処理系定義の整数値に境界調整される。オブジェクトは,そのオブジェクト型の境界調整の要求に合ったアドレス
に割り付けられる。
宣言はあるが定義のないクラス,大きさが未知な配列,又は 不完全要素型の配列を,不完全定義オブジェクト型と
呼ぶ
。不完全定義オブジェクト型 及び
0
3
型を,不完全型と呼ぶ(
*
参照)
。オブジェクトは,不完全型を
もつとして定義してはならない。
注
例えば,ライブラリ関数(
)
又は
を使ってコピーできる。
注
この規定は,
のメモリモデルを,
と互換にすることを意図している。
注
不完全定義オブジェクト型のインスタンスの大きさ 及び 配置は,不明とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
クラス型( 例えば
5
)は,翻訳単位中のある時点で不完全型であっても,後で完全型になることがある。こ
こで,型
5
は,両方の時点で同じ型とする。配列オブジェクト宣言された型は,不完全クラス型の配列であっ
てもよく,従って不完全型でありうる。そのクラスの型が翻訳単位の後の時点で完全型になった場合,その配列の型
は,完全型となる。ここで,その配列型は,二つの時点で同じ型とする。配列オブジェクト宣言された型は,翻訳単位
のある時点では大きさ未知の配列であってもよく,したがって不完全型でありえ,後で完全型になってもよい。ここ
で,それらの配列型は,二つの時点で異なる型(
:
境界値不明の配列
;
及び
:
要素の配列
;
)とする。大きさ未
知の配列へのポインタ型,又は 大きさ未知の配列の
宣言によって定義された型は,完全型にはなりえない。
例
5&
''
5
は,不完全型。
5!
&
''
は,不完全型へのポインタ。
ST
&
''
の型は,不完全型。
GA>6ST
&
''
GA>6
は,不完全型。
GA>6!
&
''
は,不完全型へのポインタ。
GA>6!!
&
Q
))&
''
不適格
3
5
は,不完全。
))&
''
不適格
3
不完全型。
))&
''
B>3
GA>6!
の大きさは既知。
R
5
Q
&
R&
''
5
は,ここで完全型になる。
SL.T
&
''
ここで
型は,完全になる。
R
5
&
Q
%
0
&
''
B>3
型は
Y5
へのポインタ
Y
%
0
&
''
不適格
3
型が異なる。
))
&
''
B>3
5
は完全。
))
&
''
不適格
3
GA>6
は,完全にはなりえない。
R
参考
宣言 及び 式に対する規則において,ど ういう文脈で不完全型が禁じられているかが規定されている。
オブジェクト型は,関数型,参照型 及び
0
3
型のいずれでもない型(
0
修飾があってもよい。)とする。
算術型(
*
),列挙型,ポインタ型,及び メンバへのポインタ型(
*
),並びに それらの
0
修飾付きのも
のを,スカラ型と呼ぶ。スカラ型,
"
互換構造体型,
"
互換共用体型(
*
),及び それらの型の配列,並びに それ
らの
0
修飾付き版を,
"
互換型と呼ぶ。
二つの型
及び
が同じ型の場合,
及び
は,配置互換な型と呼ぶ。
参考
配置互換な列挙体については,
)
で規定する。配置互換な
"
互換構造体 及び
"
互換共用体について
は,
*
で規定する。
*
基本型
文字(
)として宣言されたオブジェクトの大きさは,処理系定義である基本文字集合のすべての
要素を格納するのに十分なだけ大きくなければならない。その集合の一つの文字が文字オブジェクトに格納される場
合,その文字オブジェクトの整数値は,その文字に対応する
文字リテラルの値と等しい。
オブジェクトが負の
値をもてるか否かは,処理系定義とする。文字には,
又は
を明示的に宣言することができる。単な
る文字型(
),符号なし文字型(
) 及び 符号付き文字型(
)は,三つの別々の型
とする。それら三つは,同一量の記憶域を占有し,同一の境界調整要求(
*
)がある。すなわち,それらのオブジェ
クト表現は,同一になる。文字型では,オブジェクトを表現するすべてのビットが,値表現に関わる。符号なし文字
型では,値表現できるビットパタンのいずれもが数を表現する。この要件は,その他の型には当てはまらない。処理
系は,単なる文字型オブジェクトの値を,符号付き文字型 又は 符号なし文字型のど ちらと同じにしてもよい。ど ち
らにするかは,処理系定義とする。
符号付き整数型には,
:
;
,
:
;
,
:;
及び
:
;
の四つがある。これらの型の記憶
域は,右にあるほうが大きいか等しい。単なる
の記憶域の大きさ
は,実行環境のハード ウェア機構から自然
に決まる。その他の符号付き整数型は,特殊な要件を満たすために提供される。
注
すなわち,
ヘッダで定義されている
!
から
!"#
の範囲のすべての値をとるのに十分な大きさ
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
符号付き整数型のそれぞれに対し ,対応する符号なし 整数型( ただし ,型は異なる。)が 存在する。すなわち,
:
;
,
:
;
,
:
;
及び
:
;
のそれぞれは,対応す
る符号付き整数型と同じ大きさの記憶域 及び 境界調整要求(
*
)をもつ
。すなわち,符号付き整数型のそれぞ
れは,対応する符号なし整数型と同じオブジェクト表現をもつ。符号付き整数型の負でない値のとる範囲は,対応す
る符号なし整数型の部分的な範囲にあり,対応する符号付き整数型の値表現と符号なし整数型の値表現とは,同じで
なければならない。
と宣言された符号なし 整数は,
を法
3
とする算術規則に従わなければならない。ここで,
は,整数という特定の大きさの値表現に使うビット数とする。
独立した一つの型として
<
型がある。その値は,提供されている現地特性クラス(
)で規定している
最大拡張文字集合に含まれるメンバのすべてを,別々のコード で表現できるものとする。
<
型の大きさ,符号の
有無 及び 境界調整要求は,汎整数型のいずれかと等しく,その汎整数型のことを
<
型が基礎とする型と呼ぶ。
%
型の値は,
又は
のいずれかとする。
参考
%
型には,
,
,
又は
という型 及び 値は,ない。
%
型の値は,汎整数型の一つとして扱う。
%
型の値は,汎整数昇格に用いられる(
#
参照)
。
%
型,
型,
<
型,符号付き整数型 及び 符号なし整数型をまとめて,汎整数型と呼ぶ
。汎整数型
は,その同義語として整数型とも呼ぶ。汎整数型の表現は,純粋に
進数計算法に従った値を与える。
例
この規格では,汎整数型の表現として,
の補数,
の補数 及び 符号付き絶対値表現を許している。
浮動小数点型には,
5
型,
3 %
型 及び
3 %
型の三つがある。
3 %
型は,
5
型と同じ 又は そ
れ以上の精度をもち,
3 %
型は,
3 %
型と同じか それ以上の精度をもつ。
5
型の値集合は,
3 %
型
の値集合の部分集合になっており,
3 %
型の値集合は,
3 %
型の値集合の部分集合になっている。浮動小
数点型の値表現は,処理系定義とする。汎整数型 及び 浮動小数点型をまとめて,算術型と呼ぶ。標準テンプレート
(
)の特殊化によって,算術型のそれぞれに対し ,その処理系での最大値 及び 最小値が得ら
れる。
0
3
型の値の集合は,空とする。
0
3
型は,不完全型であって完全型になることはありえない。
0
3
型は,値を返
さない関数の返却値の型として用いる。すべての式は,
0
という型に明示的に変換することができる(
#
参
照)
。
0
3
型の式は,次のいずれかの場合を除いて,使ってはならない。
―
式文(
(
)の一つ
―
コンマ式の演算対象(
#
)の一つ
―
23
演算子の第
演算対象 又は 第
演算対象(
#(
)
―
の演算対象
―
返却値の型が
である関数の
文(
((
)中の式
参考
処理系によっては,二つ以上の基本型が同じ値表現をもつと決めている場合があるが,そうであっても,
それらの基本型は,別々の型とする。
*
複合型
複合型は,次のいずれかの方法で作ることができる。
―
既存の型のオブジェクトを要素とする配列(
参照)
―
既存の型の仮引数をもち,
,既存の型への参照,又は 既存の型のオブジェクトの,いずれかを返す関
数(
#
参照)
―
,又は 既存の型のオブジェクト 若しくは 関数(それらはクラスの静的メンバを含む)へのポインタ
(
参照)
―
既存の型のオブジェクト 又は 関数への参照。
―
種々の型のオブジェクトの並び,型・列挙体・これらのオブジェクトを操作するための関数の集まり(
*
),
及び これらの実体へのアクセスに対する制限事項の集まり(
)から構成されるクラス(
*
参照)
―
共用体,すなわち,異なる複数の型をそれぞれ異なる回数だけもつことのできるクラス(
*#
参照)
注
型とそれを指し示す型指定子との対応関係については,
で規定している。
注
これは,符号なしの算術はあふれないことを意味する。なぜならば,演算結果の値が符号なし整数型で表現できない場合には,演算結
果の値を符号なし整数型で表現できる最大値より
大きい数を法とした剰余が演算結果になるからである。
注
この規格で
値が未定義と規定しているとき( 例えば,初期化していない自動記憶期間の変数の値を調べようとしたとき),
$
でも
%
でもないことがありうる。
注
したがって,列挙体(
)は,汎整数ではない。しかし,列挙体は,
に規定するように,
型,
型,
型 及び
型に昇格できる。
注
整数についての
進数字の
!
及び
を使った位取り表現であって,多くの場合にそれぞれの位の値を加算した値を与える。それぞれ
の位の値は,そのビットに,最下位では
を,以後 順次
のべき乗を乗じたものとする。ただし,最上位のビットは例外となっている。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
―
名前付きの定数値の集まりからなる列挙体。個々の列挙体は,それぞれが異なる列挙型となる(
)
参照)
。
―
静的でないクラスメンバ
へのポインタ。これは,一つのクラスの複数のオブジェクトの中にある特定
の型のメンバを指し示す(
参照)
。
ここで述べた複合型を作る方法は,再帰的に実行できるが,その制約を,
,
,
#
及び
に規定
する。
型
のオブジェクトへのポインタを,
:
へのポインタ
;
と呼ぶ。
例
型オブジェクトへのポインタは,
:
へのポインタ
;
,クラス
のオブジェクトへのポインタは,
:
へのポインタ
;
と呼ぶ。
静的メンバへのポインタを除いて,単に
:
ポインタ
;
と書いたら,それは メンバへのポインタではない。不完全型へ
のポインタも許されるが,そのポインタを使ってできることには制約がある(
*
参照)
。オブジェクトポインタ型の
正当な値は,記憶(
)
)内のあるバイトのアドレ ス 又は 空ポインタのいずれかとする。型
のオブジェクトがア
ドレス
に置かれている場合,アドレス型
を値とする型
0
!
のポインタは,その値がどのようにして得られた
かにかかわらず,そのオブジェクトを指す
1
という。
参考
例えば,配列(
#)
)の最後の次の要素のアドレスは,そのアドレスに置かれたかもしれない配列要素の
型とは関係ないオブジェクトを指すと見なす。
ポインタ型の値表現は,処理系定義とする。配置互換な型については,それらの
0
修飾版へのポインタ,及び
0
修
飾のない版へのポインタは,同じ値表現 及び 同じ配置要求をもつ。
0
修飾付き(
*
) 又は
0
修飾なしの型
!
(
へのポインタ)のオブジェクトは,型が判らないオブ
ジェクトを指すのに使うことができる。
!
( 型
!
のオブジェクト )は,あらゆるオブジェクトへのポインタ
が保持できなければならない。
0
修飾付き 又は
0
修飾なしの
!
は,
0
修飾付き 又は
0
修飾なしの
!
と
同じ値表現 及び 同じ境界調整要求をもつ。
*
'
修飾子
*
及び
*
で説明した型は,
0
修飾なしの型であった。
0
修飾なしの完全オブジェクト型,
0
修飾なしの不完全オブジェクト型 及び 型
には,それぞれ
0
修飾付きの版が三つ,すなわち,
!
修飾版
,
0
修飾版 及び
!-0
修飾版がある。オブジェクト型という用語(
)には,オブジェクト生成時に
指定される
0
修飾子も含まれる。
《宣言指定子列》の中に
!
指定子があると,
!
修飾オブジェクト型のオブ
ジェクトの宣言となる。そのオブジェクトを定値オブジェクトと呼ぶ。宣言指定子の列の中に
0
指定子がある
と,
0
修飾オブジェクト型のオブジェクトの宣言となる。そのオブジェクトを揮発性オブジェクトと呼ぶ。宣言
指定子列の中に両方の
0
修飾子があると,
!
0
修飾オブジェクト型のオブジェクトの宣言となる。そのオ
ブジェクトを定値揮発性オブジェクトと呼ぶ。ある型の
0
修飾付き版 及び
0
修飾なし版は,別の型とするが,同
じ値表現 及び 同じ境界調整要求をもつ(
*
参照)
。
複合型(
*
)は,複合化される前の型の
0
修飾(があったとしてもそれ )によって
0
修飾されることがない。
配列型に
0
修飾を付けた場合,その
0
修飾は,配列要素の型には影響するが,配列の型自体には影響しない(
参照)
。
!
修飾されたクラスオブジェクトの場合,その中の非静的で,変更不可で,かつ非参照のデータメンバのそれ
ぞれは,
!
修飾される。
0
修飾されたクラスオブジェクトの場合,その中の非静的で非参照のデータメンバ
のそれぞれは,
0
修飾される。
!
0
修飾クラスのメンバも同様とする。
0
修飾付きの関数型について
は,
#
及び
*
で規定する。
0
修飾には( 部分)順序があって,ある型が他の型に対してより
0
修飾されているという言い方ができる。その順
序関係を,
表
(
に示す。
表
(
と
の順序関係
0
修飾なし
0
修飾なし
0
修飾なし
注
静的クラスメンバは,オブジェクト 又は 関数であり,静的クラスメンバへのポインタは,オブジェクト 又は 関数への通常のポイン
タとなる。
注
同じ値表現 及び 同じ境界調整制約をもつことは,関数の実引数,関数からの返却値 及び 共用体のメンバとして,交換可能であるこ
とを意味する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
この規格では,型を記述するのに,
0
( 又は
0
,
0
など )という記法を用いる。この記法は,任意の
0
修飾
子の集合すなわち,
,
,
,又は 空集合のいずれか一つを表している。配列型
に付けた
0
修飾は,その要素の型に作用するから,
が配列型の場合に
:0
;
は,要素がそのように修飾されてい
る配列を意味する。
0
修飾付きの配列型ど うしでは,その要素の型の
0
修飾を基にして,より多く( 又は より少な
く)
0
修飾されているという言い方ができる。
左辺値と右辺値
すべての式は,左辺値 又は 右辺値のいずれかをもたらす。
左辺値は,オブジェクト 又は 関数を参照する。クラス型 又は
0
修飾付きのクラス型の式の場合,右辺値式がオ
ブジェクトを参照することがある。
参考
組込み演算子 及び 組込み関数の呼出しの中には,左辺値をもたらすものがある。
例
8
がポインタ型の式の場合,
!8
は,
8
が指すオブジェクト 又は 関数を参照する左辺値になる。
もう一つの例を示す。
0
&
この関数は左辺値を生じるので,
の呼出しは,左辺値式となる。
参考
組み込み演算子の中には,演算対象として左辺値を要求するものがある。
例
組み込み代入演算子のすべては,左側演算対象として左辺値を要求する。
また,組み込み演算子の中には,右辺値を生じるものと,右辺値を要求するものとがある。
例
単項 及び
項の演算子
)
は,右辺値の実引数を要求し ,右辺値を結果としてもたらす。
個々の組み込み演算子に対しては,それぞれが左辺値演算対象を必要とするか否か,左辺値を生じるか否
かを,
#
に規定する。
参照を返さない関数の呼出し結果は,右辺値とする。利用者定義演算子は,関数であり,その演算子が左辺値を必
要とするか否か 又は 左辺値をもたらすか否かが,仮引数 及び 返却値の型によって決まる。
非参照型へのキャストの結果によって生じる一時的オブジェクトをもつ式は,右辺値とする(これには,関数記法
(
#
)を使ったオブジェクトの明示的生成の場合も含む。)
。
右辺値を要求する文脈に左辺値が現れた場合,その左辺値は,必ず右辺値に変換される(
,
及び
参照)
。
参照の初期化(
#
) 及び 一時的変数(
)に対しても,特定の文脈での左辺値 及び 右辺値の動作を規定
する。
クラスの右辺値は,
0
修飾付きの型をもっていてもよい。非クラスの右辺値は,常に
0
修飾なしの型をもってい
なければならない。右辺値は,常に完全型 又は
0
3
型をもっていなければならない。左辺値は,それらの型に加え
て不完全型をもつこともできる。
オブジェクトの左辺値は,そのオブジェクトを変更するために必須とする。ただし ,ある状況においては,クラス
の型の右辺値もまた,それが指しているものを変更するのに使用できる場合がある。
例
オブジェクトに対して呼び出されるメンバ関数(
*
)は,そのオブジェクトを変更できる。
関数は変更できないが,関数へのポインタは変更できる。
不完全型へのポインタは,変更できる。プログラムのある時点で指している型が完全型である場合,そのポインタ
の指すオブジェクトも変更できる。
!
修飾された式の参照先を,その式を通して変更してはならない。ただし ,それがクラス型であって,変更可
能な構成要素をもつ場合には,その構成要素を変更することができる(
)#
参照)
。
式を使用してその式が参照するオブジェクトを変更することができる場合,その式を変更可能と呼ぶ。変更可能で
ない左辺値式 又は 右辺値式を介してオブジェクトを変更しようとした場合,そのプログラムは不適格とする。
次にあげる型以外の左辺値を介し,あるオブジェクトの格納値をアクセスしようとするプログラムの動作は,未定
義とする。
―
そのオブジェクトの動的な型
―
そのオブジェクトの動的な型の
0
修飾付き版
―
そのオブジェクトの動的な型に対応する 符号付きの型 又は 符号なしの型
―
そのオブジェクトの動的な型の
0
修飾付き版に対応する 符号付きの型 又は 符号なしの型
注
例えば,コンストラクタを呼び出す式 及び クラス型を返す関数を呼び出す式は,オブジェクトを参照する。処理系によってはそのよ
うなオブジェクト上のメンバ関数を呼び出すことができるが,それらの式が,左辺値であるわけではない。
注
この列挙は,オブジェクトが別名をもちうるか状況ともちえない状況を明らかにすることを意図している。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
―
ある集成体 又は 共用体の型であって,そのメンバが上記のいずれかであるもの( 部分集成体 又は 含まれ
る共用体に対しては,再帰的に成り立つものを含む。)
―
そのオブジェクトの動的な型のある基底クラス型になっている型(
0
修飾があってもよい。)
―
型 又は
!3
型
標準変換
組込みの型に対して定められている暗黙の変換を,標準変換と呼ぶ。ここでは,そのような変換のす
べてを列挙する。標準変換手順とは,次の順で実行される標準変換の手順とする。
―
次のうち高々一つの変換
左辺値から右辺値への変換
配列からポインタへの変換
関数からポインタへの変換
―
次のうち高々一つの変換
汎整数昇格
浮動小数点数昇格
汎整数変換
浮動小数点変換
#
浮動小数点
-
整数変換
(
ポインタ変換
)
メンバへのポインタ変換
真理値変換
―
高々一つの修飾変換
参考
実行される標準変換手順は,空であってもよい。すなわち,変換なしの場合もありうる。
標準変換手順は,式に対して実行し ,その式を目的の型に変換する。
参考
次に示す構文の場合,ある型をもつ式が別の型に暗黙に変換される。
―
演算子の演算対象に使われた場合。目的の型は,その演算子の演算対象に対する要件によって
決まる(
#
参照)
。
―
文 又は 繰返し文(
(
及び
(#
参照)の条件の中で使われた場合。目的の型は,
%
型と
なる。
―
!<
文の式の中で使われた場合。目的の型は,汎整数となる(
(
参照)
。
―
初期化の値を与える式として使われた場合( 関数呼出しの実引数として使われる場合,及び
文の式として使われた場合を含む。)。目的の型は,
( 一般に )初期化される実体の型と
なる(
#
及び
#
参照)
。
式
が型
に暗黙変換できる必要十分条件は,宣言
:
%&;
が適格なこととする(
#
参照)
。ただし,
は,新
しい一時変数の名前とする。暗黙変換の効果は,この宣言によって一時変数を宣言し初期化した後,その一時変数を
変換の結果として使うのと同じとする。変換の結果は,
が参照型(
)の場合左辺値となり,そうでない場合右
辺値となる。式
は,この初期化で左辺値として使われる場合を除いて,左辺値として使われることはない。
参考
利用者定義された型については,利用者定義の変換も同様に扱われる(
参照)
。一般に,暗黙変換
手順(
)では,標準変換手順の後に利用者定義の変換が続き,さらに他の標準変換手順が続く。
文脈によっては,ある種の変換が抑止されることがある。例えば ,左辺値から右辺値への変換は,単項
演算子
0
の演算対象に対して実施しない。個々の例外については,該当の演算子 及び 構文の記述の中で
規定する。
左辺値から右辺値への変換
関数でも配列でもない型
の左辺値(
)は,右辺値に変換することができる。
が不完全型の場合,この変換が必須となるプログラムは,不適格とする。左辺値が参照するオブジェクトが型
の
オブジェクトでなく,
から派生した型のオブジェクトでもない場合,又は オブジェクトが初期化されていない場
合,この変換が必須となるプログラムの動作は,未定とする。
がクラス型でない場合,変換後の右辺値の型は,
の
0
修飾なし版とする。そうでない( クラス型の )場合,変換後の右辺値の型は,
とする。
変換結果の右辺値は,左辺値が指すオブジェクトの中に保持される値とする。左辺値から右辺値への変換が
$
注
では,クラスの右辺値は,
(オブジェクトなので)
"#
修飾付き型となりうる。これは,
$
%
&!!
と異なる。
$
%
&!!
では,
左辺値でないものは,
"#
修飾付き型をもたない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
#
)の演算対象の中で行われる場合,参照されるオブジェクトの中の値は,アクセスされない。この演算子は,
演算対象を評価しないからである。
参考
にも規定がある。
配列からポインタへの変換
:
型
の
要素からなる配列
;
という型 又は
:
型
の要素数未知の配列
;
という
型の 右辺値 又は 左辺値は,
:
型
へのポインタ
;
という型の右辺値に変換することができる。その結果は,その配
列の最初の要素へのポインタとする。
ワイド 文字列リテラルではない文字列リテラル(
)は,型
:
へのポインタ
;
の右辺値に変換することが
できる。ワイド 文字列リテラルは,型
:
へのポインタ
;
の右辺値に変換することができる。いずれの場合も,
その結果は,配列の先頭要素へのポインタとする。この変換は,適切なポインタの標的の型が明示的に存在する場合
にだけ適用され,左辺値から右辺値への変換が必要な場合には適用されない。
参考
この変換は,推奨しない(
附属書
5
参照)
。
多重定義の解決(
)における順位付けでは,この変換は,修飾変換(
)の前に行われる配列からポイン
タへの変換と考える。
例
YY
は,配列からポインタへの変換として,
:
へのポインタ
;
に変換されてから,修飾変換
によって
:
へのポインタ
;
となる。
関数からポインタへの変換
関数型
の左辺値は,型
:
へのポインタ
;
の右辺値に変換することができる。こ
の変換の結果は,その関数へのポインタとする。
参考
関数が多重定義されている場合の追加規則を
に規定している。
修飾変換
型
:
;
の
0
修飾が型
:
;
の
0
修飾よりも多い場合,型
:
へのポインタ
;
の右辺値
は,型
:
へのポインタ
;
の右辺値に変換することができる。
型
:
;
の
0
修飾が型
:
;
の
0
修飾よりも多い場合,型
:
という型の
のメンバへのポ インタ
;
の右辺値は,型
:
という型の
のメンバへのポインタ
;
の右辺値に変換することができる。
参考
関数型( メンバ関数へのポインタ型に使われる場合を含む。)が
0
修飾されることはない(
#
参照)
。
次の規則に従い,多重レベルのポインタに対しては,最上位レベルを除いて
0
修飾子を付けることができる
。
二つのポインタ型
と
とが同類であるとは,次の条件を満たす型
及び 整数
が存在することをいう。
―
が,
への
ポインタへの……
ポインタへの
ポインタとし ,かつ,
―
が,
への
ポインタへの……
ポインタへの
ポインタとする。
ここで,
は,
,
,
又は 空のいずれかとする。ポインタ型の中の先頭を除いた
組の
0
修飾子,上の例では,ポインタ型
の中の
,
,……,
の
組の
0
修飾子を,ポインタ型
の
0
修飾情報と呼ぶ。ポインタ型
の式をポインタ型
に変換できる必要十分条件は,次の条件のすべてが成立
することとする。
―
それらのポインタ型が同類である。
―
すべての
について,
に
がある場合,
にも
がある。
についても同
じとする。
―
と
とが異なる場合,
のすべての
について,
に
がある。
参考
プログラムが
!!
型のポインタを
!!
型のポインタに代入できたとすると(すなわち,次の例
の
''L
の行が許可されたとすると ),プログラムは,不注意にも
オブジェクトを変更できてしまう
( 次の例の
''+
の行で変更できてしまう。)
。
例
Q
%
ZZ
;
!
;
!!
%
&
;
''L3
許可されない。
!
%
&
;
!
%
Z7Z
;
''+3
定値オブジェクトの変更となる。
R
メンバへの多重レベルのポインタ型( メンバ先多段ポインタ型と呼ぶ。),又は ポインタ 及び メンバへのポインタ
型から成る混合多重レベルのポインタ型( メンバ先ポインタ混在多段ポインタ型と呼ぶ。)は,次の形式とする。
注
この変換は,非静的メンバ関数には適用されない。非静的メンバ関数を参照する左辺値はありえないからである。
注
これらの規則は,変換において定値安全性が保存されることを保証している。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
への
付きポインタ
への‥‥
付きポインタ
への
付きポインタ
ここで,
は,ポイン
タ 又は メンバへのポインタとし ,
は,ポインタ型でもメンバへのポインタ型でもない型とする。
二つのメンバ先多段ポインタ型,又は 二つのメンバ先ポインタ混在多段ポインタ型(それらを,
及び
とす
る。)が同類であるとは,次の条件をともに満たす型
と整数
が存在する場合とする。
―
が,
への
ポインタ
への‥‥
ポインタ
への
ポインタ
となって
いる。
―
が,
への
ポインタ
への‥‥
ポインタ
への
ポインタ
となって
いる。
メンバ先多段ポインタ型が同類の場合,並びに メンバ先ポインタ混在多段ポインタ型が同類の場合に
0
修飾子を
付加する規則は,ポインタ型が同類の場合と同じとする。
#
汎整数昇格
型,
!3
型,
!3
型,
!
型 及び
!3
!
型のいずれかの
右辺値は,その型の値すべてが
型で表現できる場合には,
型の右辺値に変換することができる。そうでない場
合,元の右辺値は,
!3
型の右辺値に変換することができる。
<
型(
*
) 又は 列挙型(
)
)の右辺値は,次にあげる型のうち,その元となる型のすべての値を表現で
きる型の中で最も左にある型の右辺値に変換することができる。
,
,
,
汎整数のビ ットフィールド(
*(
)の右辺値は,そのビ ットフィールド の値すべてを
型で表現できる場合には,
型の右辺値に変換することができる。そうでない場合,ビットフィールド のすべての値が
!3
型で表現
できる場合には,
!3
型に変換することができる。ビットフィールドが更に大きい場合には,汎整数昇格は,
行われない。ビットフィールドが列挙型をもつ場合,昇格のためには,ビットフィールドは,その列挙型のとらない
別の値として扱われる。
%
型の右辺値は,
型の右辺値に変換することができる。
は,
になり,
は,
になる。
これらの変換を,汎整数昇格と呼ぶ。
(
浮動小数点昇格
5
型の右辺値は,
3 %
型の右辺値に変換することができる。値は変わらない。
この変換を,浮動小数点昇格と呼ぶ。
)
汎整数変換
整数型の右辺値は,別の整数型の右辺値に変換することができる。列挙型の右辺値は,整数型の右
辺値に変換することができる。
目的の型が符号なしの型の場合,結果の値は,元の整数の値に合同な最小の符号なし整数になる( すなわち,符号
付きの型の表現に使うビット数を
とすると,
を法とした剰余になる。)
。
参考
の補数表現では,この変換は概念的なものとなり,ビットパターンの変更はない( 丸めがない場合)
。
目的の型が符号付きの型の場合,その値が目的の型( 及び ビットフィールド の幅)で表現できる場合には,値は変
化しない。そうでない場合,結果の値は,処理系定義とする。
目的の型が
%
型の場合については,
で規定する。元の型が
%
型の場合,
は
に,
は
に変
換される。
汎整数昇格に許される変換は,汎整数変換とはいわない。
浮動小数点変換
浮動小数点型の右辺値は,別の浮動小数点型に変換することができる。元の値が目的の型にお
いて正確に表現できる場合には,変換の結果は,正確な値表現となる。元の値が,目的の型で表わし うる値の二つの
隣接した値の中間にある場合,変換結果は,ど ちらかの値とする。ど ちらが選択されるかは,処理系定義とする。そ
うでない場合の挙動は,未定義とする。
浮動小数点昇格に許される変換は,浮動小数点変換とはいわない。
*
浮動小数点数と汎整数の間の変換
浮動小数点型の右辺値は,整数型の右辺値に変換することができる。その変
換は,切り捨て変換とする。つまり,小数部分を切って捨てる。切り捨てた値が,目的の型で表現できない場合,そ
の挙動は未定義とする。
参考
目的の型が
の場合については,
に規定する。
整数型 又は 列挙型の右辺値は,浮動小数点型の右辺値に変換することができる。結果の値は,目的の型で表せる
場合,正確な値となる。そうでない場合,目的の型で表される隣接した二つの値の間に位置するとき,ど ちらかの値
となる。ど ちらの値になるかは,処理系定義とする。
参考
汎整数の値が,浮動小数点の値で正確に表現できない場合,精度が劣化する。
元の型が
の場合,
値は
に変換され,
値は
に変換される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
ポインタ変換
ゼロと評価される右辺値をもつ整数型の汎整数定数式(
#*
)を,空ポインタ定数と呼ぶ。空
ポインタ定数は,ポインタ型に変換することができる。その結果は,その型の空ポインタ値となる。空ポインタ値は,
オブジェクト先ポインタ型 又は 関数先ポインタ型のどんな値とも区別できる値とする。同じ型の二つの空ポインタ
値は,比較で等しくなるものでなければならない。空ポインタ定数から,
0
修飾付きの型へのポインタへの変換は,
単一の変換となり,ポインタ変換の後で修飾変換(
)を行うことはない。
がオブジェクト型の場合,型
:
へのポインタ
;
の右辺値は,型
:
へのポインタ
;
の右辺値に変換する
ことができる。
:
へのポ インタ
;
から
:
へのポインタ
;
への変換結果は,あたかもそのオブジェクトが,
型
の最派生したオブジェクト(
)であるかのように( すなわち,ある基底クラスの部分オブジェクトとしてで
はなく),型
のそのオブジェクトがある記憶域の先頭位置を指すものとする。
をクラス型とし,
を
の基底クラス(
)とする場合,型
:
へのポインタ
;
の右辺値は,型
:
への
ポインタ
;
の右辺値に変換することができる。ただし ,
から基底クラス
をアクセスできない場合(
),又は
があいまいな場合(
),その変換を必須とするプログラムは,不適格とする。変換の結果は,派生クラスのオ
ブジェクトの中の基底クラスの部分オブジェクトへのポインタとする。空ポインタ値は,目的の型の空ポインタ値に
変換される。
メンバへのポインタの変換
空ポインタ定数(
)は,メンバ先ポインタ型に変換することができる。結果
は,その型の空メンバポインタ値とする。その空メンバポインタ値は,空ポインタ定数から作られたのではないメン
バ先ポインタのどんな値とも区別できる値とする。同じ型の二つの空メンバポインタ値は,比較で等しくなるもので
なければならない。空ポインタ定数から
0
修飾付き型のメンバへのポインタへの変換手順は,単一の変換とし ,メ
ンバへのポインタ変換の後に修飾変換(
)は行われない。
をあるクラス型とし ,
を
の派生クラス(
)としたとき,型
:
型
の
内メンバ先ポインタ
;
の右辺
値は,型
:
型
の型
内メンバ先ポインタ
;
の右辺値に,変換することができる。
が,アクセスできない場合
(
),あいまいな場合(
) 又は
の仮想基底クラス(
)となる場合,その変換を必須とするプログラム
は,不適格とする。変換の結果は,変換する前のメンバへのポインタと同じ メンバを参照するが,それが派生クラス
のメンバであるかのように基底クラスのメンバを参照する。結果は,
のインスタンス
の中のメンバを指す。結果
は,型
:
型
の
内メンバ先ポインタ
;
となるので,オブジェクト
への参照は,解除され うる。参照解除をし
た結果は,
内メンバ先ポインタが
の部分オブジェクト
と参照解除された場合と同じとなる。空メンバポイン
タ値は,目的の型の空メンバポインタ値に変換される。
真理値変換
算術型,列挙型,ポインタ型 及び メンバへのポインタ型の右辺値は,
%
型の右辺値に変換す
ることができる。ゼロという値,空ポインタ値 及び 空メンバポインタ値は
に変換され,その他の値はすべて
に変換される。
#
式
参考
ここでは,式の構文,式の評価順序 及び 式のもつ意味を規定する。式は,計算を指定する演算子 及び
演算対象の列から成る。式は,結果として値をもたらすが,副作用を生じることもある。
演算子を多重定義すること,すなわち,クラス型(
*
) 又は 列挙型(
)
)の式に演算子を適用すると
きの意味を多重に与えることができる。多重定義した演算子を使った場合,それは,
#
で規定するとお
り関数呼出しに変形される。多重定義した演算子については,その構文規則が
#
の規定に従うことを除
き,その演算対象の型,左辺値 及び 評価順序に対する要件は,関数呼出しの規則で代替される。演算子ど
うしの関係( 例えば ,
))
が
)%L
を意味すること )は,多重定義した演算子には保証されないし(
#
参照),
%
型の演算対象にも保証されない。
ここでは,個々の演算子について,多重定義していない型に適用したときの演算子の効果を規定する。演算子を多
重定義することによって,組込み演算子に対する規則を変えることがあってはならない。すなわち,この規格が個々
の演算子の適用対象と定めている型にその演算子を適用した場合の規則を,多重定義によって変えてはならない。し
かし ,組込み演算子も多重定義の解決に用いられ,その過程で,演算対象を組込み演算子にとって適切な型に変換す
る必要がある箇所では,利用者定義の変換が適用される。組込み演算子が選択された場合,演算対象に対してこうし
注
メンバへのポインタの変換( 基底クラスのメンバへのポインタから,派生クラスのメンバへのポインタへの変換)の規則は,オブジェ
クトへのポインタの変換(派生クラスへのポインタから,基底クラスのポインタへの変換)の規則が逆転したものになる(
及び
参照)
。この逆転によって,型の安全性を保証する。メンバへのポインタは,オブジェクトへのポインタ 又は 関数へのポインタではない
こと,及び そのようなポインタの変換規則は,メンバへのポインタには適用されないこと,に注意しなければならない。特に,メンバへ
のポインタは,
&
* に変換することができない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
た変換を適用した上で,ここでの規定に従ってその演算を施す(
及び
(
参照)
。
特に断らない限り,それぞれの演算子の演算対象間の評価順序,それぞれの式の中の部分式の評価順序 及び 副作
用の発生順序については,規定しない
。相続く二つの副作用完了点の間では,一つの式の評価によってスカラオ
ブジェクトの格納値が変わるのは,高々
回でなくてはならない。更に,直前の値は,次に格納すべき値を決定する
ためにだけアクセスされる。この要件は,完結式中の部分式の間で許されるどんな順序に対しても満たされなければ
ならない。そうでない場合,その挙動は未定義とする。
例
%
S))T&
''
挙動は規定しない。
%
,
))
))&
''
は,
O
になる。
%
))
)
L&
''
挙動は,規定しない。
%
)
L&
''
の値は,増える。
式の評価中に,数学的に定義されない結果が得られた場合,及び その型で表現可能な範囲にない結果が得られた場
合,その挙動は未定義とする。ただし ,その式が定数式(
#*
)の場合,そのプログラムは不適格とする。
参考
多くの既存の
"##
処理系は,整数オーバフローを無視する。ゼロでの除算,ゼロを除数とする余りの
計算,及び すべての浮動小数点例外の扱いは,処理系ごとに異なっているが,通常,それらの扱いをライ
ブラリ関数で調整することができる。
もとの型が
:
への参照
;
(
及び
#
)である式は,すべての解析に先立って,その型を
:
;
に調節し ,そ
の参照が表しているオブジェクト 又は 関数を指すようにして,その式を左辺値の式とする。
式がオブジェクトを指す場合,その式をオブジェクト式と呼ぶ。
演算対象として右辺値を必要とする演算子の演算対象に左辺値の式が現れた場合,その式は,次の標準変換のいず
れかを適用して右辺値に変換される。
―
左辺値から右辺値への標準変換(
)
―
配列からポインタへの標準変換(
)
―
関数からポインタへの標準変換(
)
参考
式を右辺値に変換するときに非クラス型の式の型から
0
修飾子を取り除くので,例えば,
!
型
の左辺値式を
型の右辺値式が必要なところで使うことができる。
算術型 又は 列挙型の演算対象をとる
項演算子の多くは,同様に変換を行って結果の型を得る。その目的は,二
つの演算対象に共通の型を得ることにあり,その共通の型が結果の型にもなる。その方法を,通常の算術変換と呼ぶ。
通常の算術変換は,次のとおりとする。
―
ど ちらか一方の演算対象が
3 %
型の場合,他方を
3 %
型に変換する。
―
そうではなく,ど ちらか一方の演算対象が
3 %
型の場合,他方を
3 %
型に変換する。
―
そうではなく,ど ちらか一方の演算対象が
5
型の場合,他方を
5
型に変換する。
―
そうではない場合,演算対象の両方に汎整数昇格(
#
)を行う。
―
次に,ど ちらか一方が
!3
型の場合,他方を
!3
型に変換する。
―
そうではなく,ど ちらか一方が
型で他方が
!3
型の場合,
型が
!3
型
のすべての値を表現できるときは,
!3
型を
型に変換し,表現できないときは,両方の
演算対象を
!3
型に変換する。
―
そうではなく,ど ちらか一方が
型の場合,他方を
型に変換する。
―
そうではなく,ど ちらか一方が
!3
型の場合,他方を
!3
型に変換する。
参考
これらのいずれにもあてはまらないのは,両方の演算対象が
型の場合である。
浮動小数点型の演算対象の値 及び 式の結果が,型で必要とするよりも高い精度 及び 広い数値範囲で表現される
ことがある。しかし ,それによって型が変わることはない。
#
一次式
一次式には,リテラル,名前 及び 有効範囲解決演算子
33
で修飾した名前がある。
一次式
3
リテラル
式
注
演算子間の優先順位は,直接の規定を定めないが,構文規則から決まる。
注
その結果,
型,
'
"
型 又は 列挙型は,汎整数型の一つに変換される。
注
キャスト 及び 代入演算子は,
,
及び
に規定するとおり,それぞれに固有の変換を施す。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
識別子式
識別子式
3
修飾なし識別子
修飾付き識別子
修飾なし識別子
3
識別子
演算子関数識別子
変換関数識別子
X
クラス名
テンプレート識別子
《リテラル》は,
《一次式》の一つとする。その型は,その形式によって決まる(
参照)。文字列リテラルは,
左辺値とする。その他のすべてのリテラルは,右辺値とする。
キーワード
は,非静的メンバ関数(
*
)を呼び出したときの対象となったオブジェクトへのポインタを表
す。キーワード
は,クラスの非静的メンバ関数の本体(
*
)の内部,又は コンストラクタの《メンバ初期化
子》
(
(
)の内部でしか使ってはならない。その式の型は,その関数のクラスへのポインタとする(
*
参照)
。
ただし ,必要に応じて,クラス型に
0
修飾子を付けることがある。その式は,右辺値とする。
演算子
33
に続けて,
《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》を書いたものは,
《一次式》の一つと
する。その型は,
《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》の宣言における指定による。その結果は,
《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》が表す実体とする。その実体が関数 又は 変数の場合,結果
は,左辺値とする。その《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》は,大域的な名前空間有効範囲を
もつか,
《
!
指令》
(
)
)によって大域的有効範囲において可視になっているかのいずれかでなければならない。
参考
33
を用いることによって,大域的名前空間で宣言された型,オブジェクト,関数,列挙子 又は 名前空
間を参照することができる。それらの識別子が隠ぺいされていても参照可能とする(
参照)
。
括弧で囲まれた式は,その括弧内の式と同一の型 及び 値をもつ一次子とする。括弧があることは,式が左辺値で
あるかど うかに影響を与えない。括弧で囲まれた式は,特に規定しない限り,その括弧内の式が使えるのと同じ文脈
かつ同じ意味で使うことができる。《識別子式》は,
《一次式》の制限された形式とする。
参考
《識別子式》は,演算子
(
及び 演算子
V
の後ろに書いてもよい(
##
参照)
。
《識別子》は,それが適切に宣言(
)
)されている場合に,
《識別子式》となる。
参考
《演算子関数識別子》は,
#
で規定する。
《変換関数識別子》は,
で規定する。
《テンプレー
ト識別子》は,
で規定する。
《クラス名》の前に
X
を書いたものは,デストラクタとする(
参
照)。非静的メンバ関数の定義の中では,非静的メンバを指す《識別子》は,クラスメンバアクセス式に
変換される(
*
参照)
。
《識別子式》の型は,
《識別子》の型とする。その結果は,識別子が表す実体とする。実体が関数,変数 又は データメ
ンバの場合,その結果は,左辺値とする。
修飾付き識別子
3
33
入れ子名前指定子
修飾なし識別子
33
識別子
33
演算子関数識別子
33
テンプレート識別子
入れ子名前指定子
3
クラス名・名前空間名
33
入れ子名前指定子
クラス名・名前空間名
33
入れ子名前指定子
クラス名・名前空間名
3
クラス名
名前空間名
クラスを指す《入れ子名前指定子》の直後にキーワード
(
)があって(なくてもよい。),更にその
後に,そのクラス(
*
)のメンバの名前 又は そのクラスの基底クラス(
)のメンバの名前が続いたものが,
《修
飾付き識別子》となる。
《修飾付き識別子》に現れるクラスメンバに対する名前検索は,
に規定する。結果は,
そのメンバとし ,結果の型は,そのメンバの型とする。メンバが静的なメンバ関数 又は データメンバの場合,結果
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
は,左辺値とする。
参考
クラスメンバは,潜在的有効範囲(
(
)内の任意の位置で,
《修飾付き識別子》を使って参照するこ
とができる。
《クラス名》
33
《クラス名》という形式を用い,その二つの《クラス名》が同じクラスを参照する形式をコンストラ
クタ(
)の記法とする。
《クラス名》
33
X
《クラス名》という形式を使う場合,その二つの《クラス名》は,同
じ クラスを参照しなければならない。この形式をデストラクタ(
)の記法とする。
参考
クラスを指す《型定義名》は,
《クラス名》となる(
)
参照)
。クラスの《メンバ指定》の外側にある
コンストラクタ定義 又は デストラクタ定義(
及び
)の中にある《識別子》として使う場合を
除き,クラスを指す《型定義名》を《修飾付き識別子》の中で使って,コンストラクタ 又は デストラク
タを参照してもよい。
名前空間(
)
)を指している《入れ子名前指定子》は,直後にその名前空間中のメンバ名が続いた場合(又は《
!
指令》によって可視となる名前空間のメンバの名前が続いた場合),
《修飾付き識別子》とする。
《修飾付き識別子》に
現れる名前空間メンバの名前検索は,
で規定する。結果は,そのメンバとする。結果の型は,そのメンバの
型とする。そのメンバが関数 又は 変数の場合,結果は左辺値となる。
《修飾付き識別子》において,
《識別子式》が《変換関数識別子》の場合,それの《変換型識別子》は,全体の《修
飾付き識別子》が現れる文脈,及び《入れ子名前指定子》が指すクラスの文脈の両方において,同じ型を表していな
ければならない。
クラスの非静的なデータメンバ 又は 非静的なメンバ関数を表す《識別子式》が使えるのは,次のいずれかの場合
だけとする。
―
オブジェクト式がそのメンバのクラス,又は そのクラスから派生したクラスを参照しているときに,クラ
スメンバアクセス(
##
)の一部として使う。
―
メンバへのポインタを形成するのに使う(
#
参照)
。
―
そのクラスの非静的関数 又は そのクラスから派生したクラスの非静的関数の本体の中で使う(
*
参照)
。
―
そのクラスのコンストラクタ 又は そのクラスから派生したクラスのコンストラクタの《メンバ初期化子》
の中で使う(
(
参照)
。
《テンプレート識別子》が《修飾なし識別子》として使えるのは,
)
,
)
及び
#
に規定する場合だけ
とする。
#
後置式
後置式は,左から右に結びついていく。
後置式
3
一次式
後置式
S
式
T
後置式
式並び
単純型指定子
式並び
33
入れ子名前指定子
識別子
式並び
33
入れ子名前指定子
テンプレート識別子
式並び
後置式
(
識別子式
後置式
V
識別子式
後置式
(
擬似デストラクタ名
後置式
V
擬似デストラクタ名
後置式
))
後置式
VV
P
型識別子
式
P
型識別子
式
P
型識別子
式
P
型識別子
式
式
型識別子
式並び
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
代入式
式並び
代入式
擬似デストラクタ名
3
33
入れ子名前指定子
型名
33
X
型名
33
入れ子名前指定子
テンプレート識別子
33
X
型名
33
入れ子名前指定子
X
型名
#
配列の添字付け
ある後置式の後ろに角括弧に囲まれた式が続く場合,それは後置式とする。前の式は,
:
へのポインタ
;
という型でなければならず,後の式は,列挙型 又は 汎整数型でなければならない。結果は,型
の
左辺値とする。その型
は,完全に定義されたオブジェクト型でなければならない
。 式
8LS8+T
は,
( 規定によっ
て )
!8L )8+
と同一とする。
参考
!
及び
)
の詳細は,
#
及び
#)
で規定し ,配列の詳細は,
で規定する。
#
関数呼出し
関数呼出しには,二つの種類,すなわち,通常の関数呼出し 及び メンバ関数(
*
)呼出しがあ
る
。関数呼出しの場合,後置式の後ろに括弧でくくられて,コンマで区切った式の並び(空であってもよい。)が
続く。そこに並んだ式が,その関数の実引数となる。通常の関数呼出しの場合,その後置式は,関数を参照する左辺
値(この場合,その後置式に対する関数からポインタへの標準変換(
)は,抑止される。),又は 関数型へのポイ
ンタのいずれかでなければならない。式を介して関数を呼び出す場合,その式の関数型に言語結合があり,それが呼
び出される関数の定義での関数型の言語結合と異なっているときは,その関数呼出しは,未定義とする(
)#
参照)
。
メンバ関数呼出しの場合,その後置式は,次のいずれかでなければならない。
―
暗黙のクラスメンバアクセス(
*
及び
*
) 又は 明示的なクラスメンバアクセス(
##
)であって,
その《識別子式》が関数メンバ名であるもの
―
メンバポインタ式(
##
)であって,ある関数メンバを選択するもの
その後置式にある最初の式をオブジェクト式といい,その呼出しは,そのオブジェクト式が指している 又は 参照して
いるオブジェクトのメンバに対して行われる。暗黙のクラスメンバアクセスの場合,その暗黙に想定されるオブジェ
クトは,
が指しているオブジェクトとする。
参考
という形式のメンバ関数呼出しは,
! (
と解釈される(
*
参照)
。
関数名 又は メンバ関数名の場合,その名前が多重定義(
)されていることもある。その場合,
の規則に従っ
て適切な関数が選択される。メンバ関数呼出しで呼び出す関数は,通常,オブジェクト式の静的な型に従って選択さ
れる(
参照)
。ただし,その関数が仮想関数であり,かつ《修飾付き識別子》を用いて指定していない場合,実際
に呼び出される関数は,オブジェクト式の動的な型の中で選択された関数の最終上書き関数(
)となる。
参考
ここで,その動的な型とは,そのオブジェクト式のその時点の値が指している 又は 参照しているオブ
ジェクトの型とする。そのオブジェクト式が,構築中 又は 解体中のオブジェクトを参照する場合の仮想
関数呼出しの挙動については,
)
で規定する。
呼び出される関数の宣言が,呼び出す側の有効範囲から見えない場合,そのプログラムは,不適格とする。
関数呼出しの式の型は,静的に( すなわち,キーワード
は無視して)選択した関数の返却値の型とする。
その型は,実際に呼び出される関数の型と異なっていることがある。その型は,完全オブジェクト型,参照型 又は
0
3
型のいずれかでなければならない。
関数が呼び出されたとき,個々の仮引数(
#
)は,対応する実引数によって初期化される(
#
,
及び
参照)
。関数が非静的メンバ関数の場合,その関数の中の
(
*
)は,この呼出しのオブジェクトへのポインタ
に初期化され,あたかも明示的型変換(
#
)が行われるかのように変換される。
参考
この変換に対するアクセス検査は,行われない。アクセス検査は,
( 暗黙的でもよいが )クラスメンバア
クセス演算子の中で行われる(
参照)
。
関数が呼び出されたとき,オブジェクト型の仮引数は,完全に定義されたオブジェクト型でなければならない。
参考
ただし ,仮引数が不完全なクラス型へのポインタ 又は 参照であっても構わない。しかし ,値渡しの仮
引数が不完全型であってはならない。
処理系は,仮引数の初期化において,対応する実引数に対して施す( 複数の)変換 及び/又は 仮引数の初期化用一時
変数の構築をうまく組み合わせて,余分な一時変数の構築を省いてもよい(
参照)
。仮引数の生存期間は,その
注
このことは,慣用的な書き方(
'()
)の中での添字演算子にもあてはまる。
注
静的なメンバ関数(
)は,通常の関数とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
##
仮引数を定義している関数から戻る時点で終了する。個々の仮引数の初期化 及び 解体は,呼出し側の文脈中で行う。
参考
コンストラクタ,変換関数 又は デストラクタに対するアクセス検査は,呼び出す側で関数を呼び出す時
点で行われる。関数仮引数に対するコンストラクタ 又は デストラクタが例外を送出した場合,ハンド ラ
の探索は,呼び出す側の関数有効範囲の中から始まる。特に,呼び出される関数の中に《関数監視ブロッ
ク》
(
#
)があって,そこにその例外を処理できるハンド ラがあったとしても,そのハンド ラは,無視さ
れる。
関数呼出しの値は,呼び出された関数が返却する値とする。ただし ,仮想関数の呼出しにおいて,最終上書き関数の
返却値の型が,静的に選択される関数の返却値の型と異なる場合,最終上書き関数の返却値は,静的に選択される関
数の返却値の型に変換される。
参考
関数は,定値でない仮引数の値を変更できるが,仮引数が参照型(
)である場合を除いて,その変
更が実引数の値に影響を与えることはない。その参照が
!
修飾の型への参照である場合,実引数の値
を変更するには,
を用いてその定値性を消す必要がある。仮引数が
付きの参照型の場
合,必要に応じて一時オブジェクトが作られる(
)#
,
,
,
及び
参照)
。さらに,
ポインタの仮引数を介して,定値でないオブジェクトの値を変更することができる。
関数の宣言のしかたによって,
( 省略時実引数(
(
)を宣言して )その関数の定義で定めた仮引数の個数よりも
少ない実引数を指定することができるし ,
[ 省略記号
(((
(
#
)を使うことによって]それよりも多い個数の実引
数を指定することもできる。
参考
このことは,省略記号(
(((
)がある場合を除いて,それぞれの実引数には,一つの仮引数が対応する
ことを意味する。
ある実引数に対応する仮引数がない場合でも,受取り側の関数の中で
(
)
)を呼び出すことによってそ
の実引数の値を得ることができるので,その実引数を渡すことができる。左辺値から右辺値への標準変換(
),配
列からポインタへの標準変換(
) 及び 関数からポインタへの標準変換(
)が,実引数の式に対して行われる。
その変換の後で,実引数の型が,算術型,列挙型,ポインタ型,メンバへのポインタ型 又は クラス型のいずれでもな
い場合,そのプログラムは,不適格とする。実引数の型が
"
互換でないクラス型(
*
)の場合,その挙動は未定義と
する。実引数の型が,汎整数昇格(
#
)の対象となる汎整数型 若しくは 列挙型,又は 浮動小数点昇格(
(
)の対
象となる浮動小数点型の場合,その呼出しの前に,実引数の値を昇格先の型に変換する。これらの昇格のことを,既
定の実引数昇格という。
複数の実引数の間の評価順序は,規定しない。実引数の式の評価によるすべての副作用は,関数に入る前に完了す
る。後置式 及び 実引数並びの評価の順序についても規定しない。
(
(
)という名の関数を除き,再帰呼出しを行うことができる。
関数呼出しは,その結果の型が参照の場合に限り,左辺値とする。
#
明示的型変換(関数的記法)
《単純型指定子》
(
)#
)の後に括弧で囲まれた《式並び》が続いた場合,そ
の《式並び》に与えられた値から,指定した型の値を構築する。その《式並び》がただ一つの式から成る場合,その
型変換の式は,対応するキャスト式(
#
)と同等とする( 規定の有無について同等とし,規定があれば,その意味に
おいて同等とする。)
。
《単純型指定子》がクラス型を指定している場合,そのクラス型は,完全でなければならない。
《式並び》に二つ以上の値を指定している場合,その型は,適切に宣言されたコンストラクタ(
#
及び
参照)
をもつクラスでなければならず,式
L
+
(((
は,
L
+
(((
という宣言と同等の効果をもつ。す
なわち,一時的変数
を導入し ,式の結果は,右辺値としての
の値となる。
が,配列でない完全オブジェクト型 又は
型(
0
修飾付きでもよい。)に対する《単純型指定子》
(
)#
)
のとき,式
は,指定した型の右辺値を作るが,その値は,値初期化される(
#
参照。ただし ,
の場合
は,初期化を行わない。)
。
参考
が
0
修飾付きの非クラス型の場合,結果となる右辺値の型を決めるとき,その
0
修飾子は,無視さ
れる(
参照)
。
#
擬似デスト ラクタの呼出し
ド ット演算子
(
又は 矢印演算子
V
の後ろに《擬似デストラクタ名》を付けた
表現は,型名の表す非クラス型に対するデストラクタを表す。その結果は,関数呼出し演算子
の演算対象にしか
使ってはならず,その呼出し結果の型は,
型とする。その効果は,ド ット 又は 矢印の前にある《後置式》を評
価することだけとする。
ド ット演算子の左辺は,スカラ型でなければならない。矢印演算子の左辺は,スカラ型へのポインタでなければな
らない。そのスカラ型は,そのオブジェクトの型とする。
《擬似デストラクタ名》が示す型は,そのオブジェクト型と
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#(
同じでなければならない。更に,次の形式の《擬似デストラクタ名》の中の二つの《型名》は,同じ スカラ型でなけ
ればならない。
33
入れ子名前指定子
型名
33
X
型名
そのオブジェクト型の
0
修飾なし版 及び 《擬似デストラクタ名》の指す型の
0
修飾なし版は,同じ型でなければ
ならない。
##
クラスメンバアクセス
後置式の後ろに,ドット
(
又は 矢印
V
があり,その後にキーワード
(
)
があり(ないこともある。),更に《識別子式》が続いた場合,それは一つの後置式とする。ド ット 又は 矢印の前の
後置式は,評価される
。その評価の結果が,
《識別子式》と併せて,全体としての後置式の結果を決める。
第
の形(ド ット )の場合,最初の式(オブジェクト式)の型は,
( 完全型の)
:
クラスオブジェクト
;
でなければ
ならない。第
の形( 矢印)の場合,最初の式(ポインタ式)の型は,
( 完全型の )
:
クラスオブジェクトへのポイン
タ
;
でなければならない。これらの場合,
《識別子式》は,そのクラスのメンバ 又は そのクラスの基底クラスのメン
バを指すものとしなければならない。
参考
クラスの名前は,クラス有効範囲内にある(
*
参照)ので,クラスの名前は,そのクラスの入れ子になっ
たメンバとしても扱える。
参考
#
で,演算子
(
及び 演算子
V
の後ろにある名前の検索方法を規定している。
8L
が型
:
クラス
へのポインタ
;
である場合,式
8LV8+
は,それと同等な形式
!8L (8+
に変換される。
##
のこの文以降では,第
の形(ド ット )の場合だけを取り上げて規定する
。
:
オブジェクト式
(
《識別子式》
;
を,
8L(8+
と略記する。式
8L(8+
の型 及び 左辺値の特性は,次のとおりに決まる。
##
のこの文以降では,
を使っ
て
付き 又は
なしの状況を表し ,
を使って
付き 又は
なしの状況を表し ,
を
使って
0
修飾子の任意の集合を表す(
*
参照)
。
8+
が型
:
への参照
;
をもつとして宣言した場合,
8L(8+
は,左辺値とし ,
8L(8+
の型は,
とする。そうでない
場合は,次による。
―
8+
が静的データメンバであり,
8+
の型が
であるとき,
8L(8+
は,左辺値とする。その式は,そのクラ
スの名前付きメンバを指す。
8L(8+
の型は,
とする。
―
8+
が非静的データメンバであり,
8L
の型が
:
;
であり,かつ
8+
の型が
:
;
であると
き,その式は,最初の式
8L
の指すオブジェクトの名前付きメンバを指す。
8L
が左辺値のとき,
8L(8+
は,
左辺値とする。
という記法を使って
と
との和集合を表わすこととする。すなわち,
又
は
が
のとき,
は
とする。同様に,
という記法を使って
と
の
和集合を表わすこととする。すなわち,
又は
が
のとき,
は
とする。
8+
が変更
可能なメンバの場合,
8L(8+
の型は,
:
;
とする。
8+
が変更可能でない場合,
8L(8+
の型は,
:
;
とする。
―
8+
が( 多重定義されているかもしれない)メンバ関数である場合,関数多重定義解決(
)によって,
8L(8+
が,静的メンバ関数 又は 静的でないメンバ関数のいずれを参照するかが決まる。
それが静的メンバ関数を参照しており,
8+
の型が
:
を返す関数
仮引数型並び
;
である場合,
8L(8+
は,左辺値とする。その式は,その静的メンバ関数を指す。
8L(8+
の型は,
8+
の型と同
じ ,すなわち
:
を返す関数
仮引数型並び
;
とする。
そうではなく,
8L(8+
が非静的メンバ関数を参照していて,
8+
の型が
:
を返す関数
仮引
数型並び
;
である場合,
8L(8+
は,左辺値とならない。その式は,非静的メンバ関数を指す。
その式は,メンバ関数呼出し(
*
)の左辺の演算対象としてだけ使える。
参考
式を囲む冗長な括弧は,無視される(
#
参照)
。
8L(8+
の型は,
:
を返す関数
仮引数型並び
;
とする。
―
8+
が入れ子型
!3
1
(
*
参照)である場合,その式
8L(8+
は,不適格とする。
―
8+
が メンバ列挙子であって
8+
の型が
である場合,式
8L(8+
は,左辺値ではない。
8L(8+
の型は,
と
する。
参考
:
クラスオブジェクト
;
は,構造体(
*
)であってもよいし,共用体(
*
)であってもよい。クラスに
ついては,
*
で規定する。
注
評価結果が全体の後置式の値を決めるのに必要ない場合でも(例えば《識別子式》が静的メンバを指す場合でも),評価が行われる。
注
*+
が型
クラス
へのポインタ
の場合,
*+
は,左辺値となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#)
#(
増加と減少
後置演算子
))
を作用させて得る値は,演算子を作用させる前の演算対象の値とする。
参考
得た値は,元の値のコピーとする。
この演算子の演算対象は,変更可能な左辺値でなければならない。演算対象の型は,算術型か,完全オブジェクト型
へのポインタかのいずれかでなければならない。結果を得た後で,そのオブジェクトの値は,
が加算された値に変
更する。ただし ,オブジェクトが
%
型の場合には,
を設定する。
参考
この使い方は,推奨されない(
附属書
5
参照)
。
結果は,右辺値とする。結果の型は,演算対象の型の
0
修飾なし版とする(
#)
及び
#)
参照)
。
後置演算子
VV
は,後置演算子
))
に類似して,その演算対象の値を減少させる。ただし ,その演算対象を
%
型
としてはならない点が異なる。
参考
前置演算子の増加 及び 減少は,
#
で規定する。
#)
動的キャスト
動的キャストの式
の結果は,式
を型
に変換した結果とする。
は,
完全クラス型へのポインタ 若しくは 参照,又は
:
へのポインタ
;
のいずれかでなければならない。動的キャ
ストの中で,型を定義してはならない。演算子
によって定値性を消してはならない(
#
参照)
。
がポインタ型である場合,
は,完全クラス型へのポインタの右辺値でなければならない。その結果は,型
の
右辺値とする。
が参照型である場合,
は,完全クラス型の左辺値でなければならない。その結果は,型
を参照
する左辺値とする。
要求された結果の型( 便宜上,ここではそれを
と呼ぶ。)と
の型とが同じ場合,又は
が
の型よりも多く
0
修飾されていることを除いて
と
の型とが同一である場合,その結果は,
( 必要な場合には変換された )
と
する。
がポインタであって,
の値が空ポインタ値である場合,その結果は,型
の空ポインタ値とする。
"
を
#
の基底クラスとし ,
を
:
"
へのポインタ
;
とし ,かつ
が型
:
#
へのポインタ
;
である場合,その
結果は,
の指す
#
型オブジェクトの一意な
"
型部分オブジェクトへのポインタとする。同様に,
"
を
#
の基底クラ
スとし,
を
:
"
への参照
;
とし,かつ
が型
:
#;
である場合,その結果は,
が参照する
#
型オブジェクト
の一意な
"
型部分オブジェクト
の左辺値とする。ポインタ 及び 参照のど ちらの場合でも,
は,
と同じ
か それより多い
0
修飾でなければならず,
"
は,
#
のあいまいでない基底クラスとしてアクセス可能でなければな
らない。
例
"
Q
R
&
#
3
"
Q
R
&
#!
Q
"!
%
P"!
&
''
"!
%
&
と同等
R
上のいずれでもない場合,
は,多相型(
)へのポインタ 又は 多相型の左辺値のいずれかでなければならない。
が
:
へのポインタ
;
である場合,その結果は,
の指す最派生オブジェクトへのポインタとする。そうで
ない場合,実行時の検査を行い,
が指す 又は 参照するオブジェクトを,
が指す 又は 参照する型に変換できるか
ど うかを調べる。
その実行時の検査は,論理的には次のとおりに行う。
―
の指す( 又は 参照する)最派生オブジェクトの中で,
が型
のオブジェクトの公開基底クラスの部
分オブジェクトを指し ,かつ
の指す( 又は 参照する)部分オブジェクトから型
のオブジェクトが一
つだけ派生している場合,その結果は,
型オブジェクトへのポインタ( 又は それを参照する左辺値)と
する。
―
そうでない場合,
が最派生オブジェクトの公開基底クラスの部分オブジェクトを指し( 又は 参照し ),
最派生オブジェクトが
のあいまいでない公開基底クラスをもつ場合,その結果は,最派生オブジクトの
型部分オブジェクトへのポインタ( 又は それを参照する左辺値)とする。
―
上のいずれでもない場合,実行時の検査に失敗したとする。
ポインタ型へのキャストに失敗した場合のキャストの値は,要求される結果の型の空ポインタ値とする。参照型へ
のキャストに失敗した場合は,例外
を送出する(
#
参照)
。
例
6
Q
&
R&
注
が指す 又は 参照する最派生のオブジェクト(
)がこれ以外の
,
オブジェクトを基底クラスとしてもっていてもよいが,それら
は無視される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
"
Q
&
R&
#
3
6
"
Q
R&
Q
#
&
"!
%
"! 0&
''
保護を破るためにキャストが必要。
6!
%
0&
''
公開の派生であり,キャスト不要。
#0
%
P#0
!
&
''
失敗
%
P6!
&
''
失敗
%
P"!
&
''
失敗
%
P6!
0
&
''
成功
%
P"!
0
&
''
失敗
R
8
3
#
"
Q
R
&
9
3
8
#
Q
R
&
Q
9
&
6!
%
0
&
''
成功
3
一意な
6
が見つかる。
#!
%
P#!
&
''
失敗
3
.
を生じる。
に二つの
''
#
型部分オブジェクトがある。
8!
%
8!
&
''
不適格
3
仮想基底からのキャスト。
8!
L
%
P8!
&
''
成功
R
参考
構築中 又は 解体中のオブジェクトに動的キャストを適用したときの挙動については,
)
で規定する。
#
型の識別
が《式》に作用したときの結果は,静的な型
33
(
#
) 若しくは
動的な型
33
の左辺値,又は
とする。ここで,
は,
33
から派
生した処理系定義のクラスとし,
#
に規定する動作を行うクラスとする
。この左辺値が参照するオブジェク
トの生存期間は,プログラム終了までとする。プログラム終了時に
オブジェクトのデストラクタが呼び出
されるか否かについては,規定しない。
が多相的クラス型(
)の左辺値の《式》に作用した場合,その結果は,その左辺値が参照する最派生オ
ブジェクト(
)
(すなわち動的な型のオブジェクト )の型を表す
オブジェクトの参照とする。その左辺
値の式がポインタに単項演算子
!
を適用して得られたもの
であって,そのポインタが空ポインタ値(
)の
場合,
をその式に作用させたときには,例外
(
#
)を送出する。
が多相的クラス型の左辺値以外の《式》に作用した場合,その結果は,その式の静的な型を表す
のオブジェクトの参照とする。左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
),及び
関数からポインタへの標準変換(
)は,その式には適用されない。式の型がクラス型の場合,そのクラスは,完
全に定義されていなければならない。その式の評価は,行われない。
が《型識別子》に作用した場合,その結果は,その《型識別子》の型を表す
のオブジェクトの
参照とする。
《型識別子》の型が参照型の場合,その
式の結果は,その参照型を表す
のオブジェク
トの参照とする。
《型識別子》の型がクラス型であるか,クラス型への参照である場合,そのクラスは,完全に定義
されていなければならない。型は,その《型識別子》の中で定義してはならない。
の演算対象になっている左辺値式 又は 《型識別子》の最上位の
0
修飾子は,常に無視される。
例
#
Q
(((
R
&
#
L
&
#
+
&
L
%%
+
&
''
となる。
#
%%
#
&
''
となる。
#
%%
+
&
''
となる。
#
%%
#0
&
''
となる。
ヘッダ
(
#
)を
を用いる前に取り込んでいない場合,そのプログラムは,不適格とする。
参考
解体中のオブジェクトに
を作用させたときの挙動については,
)
で規定する。
注
このクラスの名前としては,
(&&
%
を推奨する。
注
をポインタ型の式とするとき,
,
,
,
,
などが,これに当たる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#*
#*
静的キャスト
静的キャストの式
の結果は,式
を型
に変換した結果とする。
が
参照型の場合,その結果は,左辺値とする。そうでない場合,その結果は,右辺値とする。静的キャストの中で,型
を定義してはならない。演算子
は,定値性を消してはならない(
#
)
。
静的キャスト
を使って式
を型
に明示的に変換することができるのは,一時的変数(
#
)
を導入した宣言
&
が適格となる場合とする。その明示的変換の効果は,一時的変数
を宣言し初期化した上
で,変換結果として
を使うことと同じとする。その結果は,
が参照型(
)の場合は左辺値とし ,そうでな
い場合は右辺値とする。式
は,
の初期化が
を左辺値として使っている場合かつその場合に限り,左辺値として
使われる。
そうでない場合,静的キャストは,次に列挙する変換のいずれかを行う。これらを除く明示的な変換は,静的キャ
ストによって行ってはならない。
すべての式は,明示的に型
:
;
に変換することができる。その式の値は,捨てられる。
備考
しかし,その値が一時的変数(
)のものである場合,その変数に対するデストラクタは,通常の時
点まで実行されず,その変数の値は,デストラクタを実行するために保持される。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
),及び 関数からポインタへの標準変
換(
)は,式には適用されない。
"
がクラス型であって,
#
が
"
の派生型(
)である場合,次の条件をすべて満たすときには,型
:
";
の左辺
値を,型
:
#
への参照
;
にキャストすることができる。
―
:#
へのポインタ
;
から
:"
へのポインタ
;
への正当な標準変換が存在する(
参照)
。
―
が,
と同じか 又は より多く
0
修飾されている。
―
"
は,
#
の仮想基底クラスではない。
その結果は,型
:
#;
の左辺値とする。型
:
";
の左辺値が,実際は型
#
のオブジェクトの部分オブジェクトで
ある場合,その左辺値は,型
#
を囲むオブジェクトを参照する。そうでない場合,キャストの結果は,未定義とする。
例
"
Q
R
&
#
3
"
Q
R
&
#
&
"
0
%
&
P#0
&
''
元のオブジェクト
への左辺値を生成する。
標準変換手順(
)の逆変換は,左辺値から右辺値への変換(
),配列からポインタへの変換(
),関数か
らポインタへの変換(
) 及び 真理値変換(
)を除き,静的キャストを明示的に使うことによって行うことが
できる。この静的キャストの演算対象にも,左辺値から右辺値への変換(
),配列からポインタへの変換(
),
関数からポインタへの変換(
) 及び 真理値変換(
)が適用される。この静的キャストは,定値性(
#
)
を消してはならない。更に,この静的キャストには,個々の場合に対しての追加規則を設ける。
汎整数型 又は 列挙型の値は,明示的に列挙型に変換することができる。元の値が変換先の列挙型の値の範囲内に
ある場合,その結果の値は元の値のままとする(
)
参照)
。そうでない場合,結果の列挙型の値は,未規定とする。
"
を基底クラスとし ,
#
を
"
の派生クラスとする。次の条件をすべて満たす場合,型
:
"
へのポインタ
;
の右辺
値は,型
:
#
へのポインタ
;
の右辺値に変換することができる。
―
:#
へのポインタ
;
から
:"
へのポインタ
;
への正当な標準変換が存在する。
―
が
と同じか 又は より多く
0
修飾されている。
―
"
が
#
の仮想基底クラスではない。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。型
:
"
へのポインタ
;
の右辺値が,実際に型
#
のオブジェクトの
"
型部分オブジェクトを指す場合,結果のポインタは,それを包む型
#
のオブジェクトを指す。そ
うでない場合,キャストの結果は,未定義とする。
"
を
#
の基底クラスとする。次の条件をすべて満たす場合,型
:
型の
#
のメンバへのポインタ
;
の右辺値は,
型
:
型の
"
のメンバへのポインタ
;
の右辺値に変換することができる。
―
型
:
型の
"
のメンバへのポインタ
;
から型
:
型の
#
のメンバへのポインタ
;
への正当な標準変換(
)
が存在する。
―
が
と同じか 又は より多く
0
修飾されている。
注
関数型( メンバ関数型へのポインタの中で使われる関数型を含む。)が
"#
修飾されることはない(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
空メンバポインタ値(
)は,目的の型の空メンバポインタ値に変換される。クラス
"
が元のメンバを含む場合,
又は
"
が元のメンバを含むクラスの基底クラス 若しくは 派生クラスである場合,結果のメンバポインタは,元のメ
ンバを指す。そうでない場合,キャストの結果は,未定義とする。
参考
クラス
"
は,元のメンバを含んでいる必要はないが,メンバポインタの参照はずしの対象になっている
オブジェクトの動的な型は,元のメンバを含んでいなければならない(
##
参照)
。
型
:
へのポインタ
;
の右辺値は,型
:
へのポインタ
;
の右辺値に変換することができる。ここで,
はオブジェクト型とし,
は,
と同じか 又は より多く
0
修飾されているとする。オブジェクトへのポインタ
型の値は,
:
へのポインタ
;
に変換した後で元のポインタ型に戻すと,元の値に戻る。
#
強制キャスト
強制キャストの式
の結果は,式
を型
に変換した結果とす
る。
が参照型の場合,結果は左辺値とする。そうでない場合,結果は右辺値とし ,左辺値から右辺値への標準変換
(
),配列からポインタへの標準変換(
),及び 関数からポインタへの標準変換(
)を式
に対して行う。
強制キャスト内で,型を定義してはならない。強制キャストで明示的に行うことができる変換を次に列挙する。それ
ら以外の変換は,強制キャストで明示的に行うことはできない。
演算子
は,定値性を消すことがあってはならない。
参考
:
定値性を消すキャスト
;
については,
#
で規定する。ここでの制約に従っている限り,演算子
を使って,式をそれ自身の型にキャストしてもかまわない。
強制キャストが行う写像は,処理系定義とする。
参考
元の値と異なる表現を生じてもよいし ,同じままでもよい。
ポインタは,それを保持するのに十分な大きさをもつ任意の汎整数型に明示的に変換することができる。その写像
関数は,処理系定義とする。
参考
想定するマシンのアドレス機構を知っている人には驚くほどではないであろう。
汎整数型 又は 列挙型の値は,明示的にポインタに変換することができる
。ポインタは,十分な大きさの整数
(そういうものが処理系にあった場合)に変換した上で,同じポインタ型に戻すと元の値になる。そうでない場合,ポ
インタと整数との間の値の写像は,処理系定義とする。
関数へのポインタは,別の型の関数へのポインタに明示的に変換することができる。ある関数の定義で用いられた
関数型(
#
)とは異なる関数型へのポインタを介して関数呼出しを行った効果は,未定義とする。型
:
へのポ
インタ
;
の右辺値から型
:
へのポ インタ
;
(ここで
及び
は,関数型とする。)へのポインタ変換の結果は,
それを元の型に戻すと元のポインタ値に戻ることを除いて,未規定とする。
参考
ポインタ変換の詳細については,
で規定する。
オブジェクトへのポインタは,別の型のオブジェクトへのポインタに明示的に変換することができる
。型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
へのポインタ変換(ここで,
及び
はオブジェクト型であっ
て,
の境界調整要求が
よりも厳しくないとする。)の結果は,それを元の型に戻したときに元の値に戻ること
を除いて,未規定とする。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。
及び
が,ともに関数型 又は ともにオブジェクト型である場合,型
:
型の
のメンバへのポインタ
;
の右
辺値は,型
:
型の
のメンバへのポインタ
;
に明示的に変換することができる
。空メンバポインタ値(
)
は,目的の型の空メンバポインタ値に変換することができる。その変換結果は,次の場合を除き,未規定とする。
―
型
:
メンバ関数へのポインタ
;
の右辺値を,別の型
:
メンバ関数へのポインタ
;
に変換し ,それを元の型に
戻した場合,元のメンバポインタ値に戻る。
―
型
:
型の
のメンバへのポインタ
;
の右辺値を,型
:
型の
のメンバへのポインタ
;
に変換し(こ
こで,
の境界調整要求は,
よりも厳し くないとする。),それを元の型に戻した場合,元のメンバ
ポインタ値に戻る。
型
:
へのポインタ
;
の式を,型
:
へのポインタ
;
に強制キャストで明示的に変換できる場合,型
の左辺値
の式は,型
:
への参照
;
にキャストすることができる。すなわち,参照の強制キャスト
0
は,組込み演算子
0
及び
!
を使った変換
!
!0
と同じ効果をもつ。結果は,元の左辺値と
注
汎整数の定数式(
)で値がゼロのものを変換すると,常に空ポインタ(
)となる。しかし ,それ以外の式で値がたまたまゼ
ロのものを変換しても,空ポインタとなるとは限らない。
注
それらの型は,強制キャストが定値性を消してはならないという全体としての制約を満たしている限り,その
"#
修飾子が異なってい
てもよい。
注
強制キャストが定値性を消してはならないという全体的な制約を満足している限り,
及び
は,その
"#
修飾子が異なっていて
もよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
同じオブジェクトを参照する左辺値となるが,型は異なる。一時的変数を作らず,コピーも行わず,コンストラクタ
関数(
)もデストラクタ関数(
)も呼び出さない。
#
定値性キャスト
定値性キャストの式
の結果は,型
をもつ。
が参照型の場合,結
果は,左辺値とする。そうでない場合,結果は右辺値とし,左辺値から右辺値への標準変換(
),配列からポイン
タへの標準変換(
) 及び 関数からポインタへの標準変換(
)を式
に対して行う。定値性キャスト内で,型
を定義してはならない。定値性キャストで明示的に行うことができる変換を次に列挙する。それ以外の変換は,定値
性キャストで明示的に行ってはならない。
参考
ここでの制約を満たしている限り,
演算子を使って,式をそれ自身の型にキャストしても
よい。
二つのポインタ型
及び
について,
が,
へのポインタ
への…ポインタ
へのポイン
タ
であって,
が,
への
ポインタへの…
ポインタへの
ポインタである場合(こ
こで,
は,任意のオブジェクト型 又は
型とし ,
と
とが異なる
0
修飾であってもよい。),
型
の右辺値は,定値性キャストで明示的に
型に変換することができる。ポインタの定値性キャストの結果は,元の
オブジェクトを参照する。
へのポ インタが定値性キャストによって
へのポインタ型に明示的に変換できる場合( ここで
及び
は,共にオブジェクト型とする。),型
の左辺値は,
0
によって型
の左辺値に変換すること
ができる。定値性キャストの参照の結果は,元のオブジェクトを参照する。
データメンバへのポインタ,データメンバへの多重レベルポインタ 及び ポインタとデータメンバへのポインタと
が混合した多重レベルポインタ(
)に対する定値性キャストの場合についても,
の規則は,ポインタ
に対するのと同じとする。メンバへのポインタの
:
メンバ
;
という属性は,定値性キャストで加えたり落としたりす
る
0
修飾子を決める際には無視される。データメンバへのポインタの定値性キャストの結果は,データメンバへの
元の(キャスト前の )ポインタと同じ メンバを参照する。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。空メンバポインタ値(
)は,目的の型の空
メンバポインタ値に変換される。
参考
オブジェクトの型に依存するが,定値性キャストを使って定値修飾子
を落としてしまって得たデー
タメンバのポインタ,左辺値 又は ポインタを介して書込みを行なうと,未定義の動作(
)#
)を生じ
るかもしれない。
定値性を消すキャストの手順は,次による。ここで,
及び
は,型を示す。次の
及び
を二つのポイ
ンタ型とする。
は,
!
…
!
とし ,
は,ポインタ型ではないとする。
は,
!
…
!
とし ,
は,ポインタ型ではないとする。
を,
とする。
から
へのキャストによって定値性を消すことができる条件は,ある非ポインタ型
に対し ,
…
から
…
への暗黙の変換(
)が存在しない場合とする。
型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
の右辺値へのキャストが定値性を消すことができる場
合,参照型にキャストして型
の左辺値から型
の左辺値にすることによって定値性を消すことができる。
型
:
型のデータメンバ
へのポ インタ
;
の右辺値から,型
:
型のデータメンバ
へのポインタ
;
の右辺値
へのキャストが定値性を消すことができるのは,型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
の右辺値
へのキャストが定値性を消すことができる場合とする。
メンバへの多重レベルポインタ,ポインタと メンバへのポインタとが混合した多重レベルポインタ(
)に対し
て,
という
0
修飾子がキャストで消すことができるか否かを決めるとき,メンバへのポインタの
:
メンバ
;
と
いう属性は,無視される。
注
この変換を,英語では
(
(型の語呂合わせ)と言うことがある。
注
定値性キャストは,定値修飾子を落とす変換だけに制限されているのではない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
参考
0
修飾だけを変更する変換の中には,定値性キャストを使って実行できないものもある。例えば ,関数
へのポインタど うしの変換は,その変換によって未定義の動作を起こす値が生じるので,対象になってい
ない。同様の理由で,メンバ関数間の変換,特に,定値のメンバ関数へのポインタから,定値でないメン
バ関数へのポインタにする変換は,対象になっていない。
#
単項式
単項演算子をもつ式は,右から左に結びついていく。
単項式
3
後置式
))
キャスト式
VV
キャスト式
単項演算子
キャスト式
$
単項式
$
型識別子
<
式
3
式
単項演算子
3
次のいずれか
!
0
)
V
[
X
#
単項演算子
単項演算子
!
は,間接参照を行う。それが作用する式は,オブジェクト型へのポインタ 又は 関
数型へのポ インタでなければならず,結果は,その式が指すオブジェクト 又は 関数を参照する左辺値とする。式の
型が
:
へのポインタ
;
である場合,結果の型は,
とする。
参考
不完全型へのポインタは,
の場合を除き,参照をはずすことができる。得られた結果の左辺値
は,限られた方法で( 例えば ,参照を初期化するために )だけ使える。その左辺値は,右辺値に変換して
はならない(
参照)
。
単項演算子
0
の結果は,その演算対象へのポインタとする。演算対象は,左辺値 又は 《修飾付き識別子》でなけ
ればならない。演算対象が左辺値の場合,その式の型が
のとき,結果の型は,
:
へのポインタ
;
とする。特に,型
:
;
のオブジェクトのアドレスは,
:
へのポインタ
;
となる(
0
修飾子は変わらない。)
。演算対象が《修飾
付き識別子》の場合,メンバが型
の静的メンバのとき,結果の型は,単なる
:
へのポインタ
;
とする。メンバが
型
のクラス
7
の非静的メンバのとき,結果の型は,
:
型
のクラス
7
のメンバへのポインタ
;
とする。
例
6
Q
&
R&
"
3
6
Q
R
&
(((
0"33
(((
''
633!
という型をもつ。
参考
%
属性の非静的データメンバ(
)
)から成るメンバへのポインタは,その非静的データメンバ
に関する
%
指定子を反映しない。
メンバへのポインタが形成されるのは,明示的に
0
を使用し ,その演算対象を括弧なしの《修飾付き識別子》にし
たときにだけとする。
参考
すなわち,
《修飾付き識別子》に括弧をつけた式
0
《修飾付き識別子》
は,
:
メンバへのポインタ
;
と
いう型の式を形成しない。非静的メンバ関数を指す《修飾付き識別子》から型
:
メンバ関数へのポインタ
;
への暗黙の変換が存在しない( 関数への左辺値から
:
関数へのポインタ
;
(
)への変換は存在する。)の
で,
《修飾付き識別子》だけの場合も,
:
メンバへのポインタ
;
という型の式を形成しない。更に,
《修飾な
し識別子》の場合も,その修飾なし識別子のクラスの有効範囲内においてさえ,メンバへのポインタでは
ない。
不完全型のオブジェクトのアドレスを得ることができるが,そのオブジェクトの完全型がメンバ関数として
0
を宣言しているクラス型である場合には,その動作は未定義とする( 診断は,必要ない。)
。
0
の演算対象は,ビッ
トフィールド であってはならない。
多重定義関数(
)のアドレスは,どの版の多重定義関数が参照されるかが一意に決まる文脈でだけ得られる(
参照)
。
参考
文脈によって,演算対象が静的メンバ関数なのか非静的メンバ関数なのかが決まってしまうことがある
ので,文脈は,その式が型
:
関数へのポインタ
;
なのか型
:
メンバ関数へのポインタ
;
なのかを決めるのに
も影響を与える。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
単項演算子
)
の演算対象の型は,算術型,列挙型 又は ポインタ型でなければならず,その結果は,実引数の値と
する。汎整数 又は 列挙体の演算対象に対しては,汎整数昇格が行われる。その結果の型は,昇格した演算対象の型
とする。
単項演算子
V
の演算対象の型は,算術型 又は 列挙型でなければならず,その結果は,符号を反転させた演算対象
の値とする。演算対象が汎整数 又は 列挙体の場合,汎整数昇格が行われる。符号なしの型の場合の符号反転の計算
は,
からの減算によって行われる。ここで
は,昇格した演算対象のビット数とする。結果の型は,昇格された
演算対象の型とする。
論理否定演算子
[
の演算対象は,暗黙に
%
型に変換される(
参照)
。その値は,変換された演算対象の値が
偽のとき真とし ,それ以外のとき偽とする。結果の型は
%
型とする。
X
の演算対象は,汎整数型 又は 列挙型でなければならず,結果は,演算対象の
の補数とする。汎整数昇格が行
われる。結果の型は,昇格した演算対象の型とする。
5
がクラス名の場合,単項式
X5
にはあいまい性がある。そ
のあいまい性は,
X5
をデストラクタの参照として扱うのではなく,むしろ
X
を単項の補数演算子として扱うことに
することによって解決される。
#
増加 及び 減少
接頭語
))
の演算対象には,
が加算される。ただし ,
%
型の場合には,
が設定さ
れる(この使い方は推奨されない。)
。演算対象は,変更可能な左辺値でなければならない。演算対象の型は,算術型
であるか,又は 完全に定義されたオブジェクト型へのポインタでなければならない。その値は,演算対象の新たな値
となる。それは,左辺値とする。
が
%
型でない場合,式
))
は,
)%L
と同等とする。
参考
変換については,加算(
#)
) 及び 代入演算子(
#)
)で規定している。
接頭語
VV
の演算対象には,
が減算される。演算対象は,
%
型であってはならない。接頭語
VV
の演算対象に
対する要件 及び その結果の特性は,この制限を除き,接頭語
))
と同じとする。
参考
後置式の増加,減少については,
#(
で規定している。
#
-"
演算子
演算子
$
によって,演算対象のオブジェクト表現のバイト数が得られる。演算対象は,
式 又は 括弧付きの《型識別子》のいずれかとする。式の評価は,行われない。演算子
$
は,次のいずれに対し
ても作用させてはならない。
―
関数 又は 不完全型である式
―
列挙子のすべてを宣言し終わっていない列挙型
―
これらの型の括弧付きの名前
―
ビットフィールド を示す左辺値
$
,
$
及び
$
の値は,
とする。
$
をその他の基本
型(
*
)に作用させた結果は,処理系定義とする。
参考
特に
$
と
$
は,処理系定義とする。
参考
バイトについては
)
で規定し ,オブジェクト表現は
*
で規定する。
参照 又は 参照型に作用させた場合,その結果は,参照される型の大きさとする。クラスに作用させた場合,その
結果は,そのクラスのオブジェクトのバイト数とし ,その型のオブジェクトをある配列内に置くために詰め物が必要
であれば,その詰め物も含んだ値とする。最派生したクラスの大きさは,
以上とする(
参照)
。
$
を基底ク
ラス部分オブジェクトに作用させた結果は,その基底クラスの型の大きさとする
。配列に作用させた場合,結果
は,その配列の全体のバイト数とする。すなわち,
要素からなる配列の大きさは,
要素の大きさの
倍となる。
演算子
$
は,関数へのポインタには作用させてよいが,関数そのものには直接作用させてはならない。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
) 及び 関数からポインタへの標準
変換(
)は,
$
の演算対象には適用しない。
!J
式の中で,型を定義してはならない。
結果は,
!J
型の定数とする。
参考
$
は,標準ヘッダ
(
)の中で定義されている。
#
+
式
<
式は,
《型識別子》
(
) 又は 《生成型識別子》に作用させたとき,それらのオブジェクトを作
ろうとする。そのオブジェクトの型を,割付け型と呼ぶ。割付け型は,総体オブジェクト型でなければならず,抽象
クラス型 又は その配列としてはならない(
)
,
*
及び
参照)
。
参考
参照そのものは,オブジェクトではないので,参照を《
<
式》によって作ることはできない。
注
-%.
が
である必要はない。
注
基底クラス部分オブジェクトの実際の大きさは,その部分オブジェクトに
-%
を作用させた結果より小さくてもよい。それは,仮
想基底クラスであることと,基底クラス部分オブジェクトに対する詰め物要求がより緩いことによる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
参考
《型識別子》は,
0
修飾された型であってもよい。その場合,
《
<
式》によって作られるオブジェクト
は,
0
修飾された型になる。
<
式
3
33
生成位置指定
生成型識別子
生成初期化子
33
生成位置指定
型識別子
生成初期化子
生成位置指定
3
式並び
生成型識別子
3
型指定子列
<
宣言子
<
宣言子
3
ポインタ演算子
<
宣言子
直接
<
宣言子
直接
<
宣言子
3
S
式
T
直接
<
宣言子
S
定数式
T
生成初期化子
3
式並び
《
<
式》によって作られる実体は,動的記憶期間(
)
)をもつ。
参考
その実体の生存期間は,それが作られた有効範囲には,必ずしも制約されない。
実体が配列でないオブジェクトの場合,
《
<
式》は,作ったオブジェクトへのポインタを返す。配列の場合には,配
列の先頭要素へのポインタを返す。《
<
式》中の《生成型識別子》は,
《
<
宣言子》が可能な限り長くつながった
列とする。
参考
これによって,宣言子の演算子(
0
,
!
,
S
T
)と,それらの式に当たる部分との間のあいまいさをなく
している。
例
!
&
''
構文エラー
3
!
と構文解析され,
''
!
とは解析されない。
ここで
!
は,ポインタ宣言子であって,乗算の
!
ではない。
参考
《
<
式》の《生成型識別子》中の括弧が,重大な効果を引き起こすことがある。
例
!SL.T
&
''
エラー
この式は,次のように結合されるので不適格とする。
!SL.T
&
''
エラー
そうではなくて,
演算子に明示的に括弧を付けた版は,複合型(
*
)のオブジェクトを
作るのに使うことができる。
!SL.T
&
この例は,
:
実引数がなくて
型を返却値とする
;
関数へのポインタが
個ある配列の割付
けを行う。
《型指定子列》は,クラス宣言 又は 列挙体宣言を含んでいてはならない。
割り付けたオブジェクトが配列の場合( すなわち,
《直接
<
宣言子》の構文を使う場合,又は 《生成型識別子》
若しくは 《型識別子》が配列型を示す場合),
《
<
式》によって,配列の( 存在すれば )先頭要素へのポインタが得
られる。
参考
及び
SL.T
の型は,
!
になり,
STSL.T
の型は,
! SL.T
になる。
《直接
<
宣言子》中の《定数式》は,すべて汎整数定数式(
#*
)でなければならず,評価した値が正でなけれ
ばならない。
《直接
<
宣言子》中の《式》は,負でない値をもつ 汎整数型(
*
) 又は 列挙型でなければなら
ない。
例
が
型の変数である場合,
STS/T
は,
(
が,
《直接
<
宣言子》中の《式》に当たるので )
適格とする。しかし ,
S/TST
は,
(
が,
《定数式》ではないので )不適格とする。
が負の場
合,
STS/T
の効果は,未定義とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(#
《直接
<
宣言子》中の《式》の値がゼロの場合,割付け関数が呼び出され,要素のない配列が割り付けられる。
《
<
式》は,割付け関数(
)
)を呼び出し ,オブジェクトのための記憶域を確保する。
《
<
式》が例外を
送出して終了した場合,解放関数(
)
)を呼び出して記憶域を解放してもよい。その割付け型が配列ではない場
合,割付け関数の名称は,
とし,解放関数の名称は,
とする。その割付け型が配列
の場合,割付け関数の名称は,
ST
とし ,解放関数の名称は
ST
とする。
参考
処理系は,大域的割付け関数の省略時定義版を提供しなければならない(
)
,
及び
参照 )。
"##
のプログ ラムは,これらの関数を代替する定義(
)
) 及び/又は クラス固有の版
(
#
)をもつことができる。
《
<
式》が単項演算子
33
で始まる場合,割付け関数名の検索は,大域的有効範囲で行われる。そうではなくて,
割付け型がクラス型
又は その配列型の場合,割付け関数名の検索は,
の有効範囲内で行われる。この検索でそ
の名前が見つからなかったとき,又は 割付け型がクラス型でないときには,割付け関数名の検索は,大域的有効範囲
内で行われる。
《
<
式》は,必要とする領域の大きさを,型
33$
をもつ第
実引数として割付け関数に渡す。その実
引数は,生成するオブジェクトの大きさ以上でなければならない。オブジェクトが配列の場合に限り,生成するオブ
ジェクトの大きさよりも本当に大きくてもよい。
又は
の配列の場合,
《
<
式》の結果と割付け
関数が返すアドレスとの差は,生成する配列の大きさを超えない任意のオブジェクト型の中で最も厳しい境界調整要
求(
*
)の値の整数倍でなければならない。
参考
割付け関数は,どんなオブジェクト型に対しても,その型に適切に境界調整された記憶域へのポインタ
を返すと仮定されているので,配列割付けオーバヘッド に対するこの制約によって,文字配列を割り付け
た後で,そこに別の型のオブジェクトを配置しなおすという慣用手法が可能になる。
《生成位置指定》の構文は,付加的な実引数を割付け関数に供給するために使う。それが使われる場合,要求領域
量( 第
実引数) 及び 《
<
式》の《生成位置指定》部分の式( 第
実引数 及び その後続の実引数)から成る実引
数並びを組立てて作られる関数呼出しに対して,多重定義解決が実施される。その第
実引数は,
!J
型とし ,残
りの実引数は,
《生成位置指定》中の式ごとの型となる。
例
―
の結果は,
$
の呼出しと同等になる。
―
+
の結果は,
$
+
の呼出しと同等になる。
―
S/T
の結果は,
ST$
!/
)
の呼出しと同等になる。
―
+
S/T
の結果は,
ST$
!/
)!
+
の呼出しと同等になる。
ここで,
及び
!
は,配列割付けオーバヘッド を表す負でない値とする( 値そのものは,未規定とす
る。)。
《
<
式》の結果は,
ST
の返却値から,この量だけ指し引いた値となる。このオー
バヘッドは,すべての配列の《
<
式》
(ライブラリ関数
ST33$
!
を参
照する場合も含む。)に適用され,位置指定割付け関数に対しても適用される。そのオーバヘッド の量は,
の呼出しごとに変わってもよい。
参考
割付け関数に空の《例外指定》
(
#
)
が宣言されていない場合,記憶域の割付けに失敗する
と,例外
が送出される(
#
及び
参照)
。失敗しなかった場合,空でないポインタ値
が返る。割付け関数に空の《例外指定》
が宣言されている場合には,記憶域割付けの失敗を空の
ポインタ値を返すことによって示し ,失敗ではないことを空でないポインタ値を返すことによって示す。
割付け関数が空を返した場合,初期化は行われていず,解放関数を呼び出されていず,
《
<
式》の値は,空になる。
参考
割付け関数が空ではない値を返した場合,その値は,そのオブジェクト用に確保された記憶域ブロック
へのポインタでなければならない。その記憶域ブロックは,適切に境界調整され要求の大きさをもつもの
としてよい。生成されたオブジェクトのアドレスは,オブジェクトが配列の場合には,そのブロックのア
ドレスに一致しないかもしれない。
型
のオブジェクトを作る《
<
式》は,そのオブジェクトを次のとおりに初期化する。
―
《生成初期化子》が省略されている場合
が,
(
0
修飾付きでもよいが )
"
互換でないクラス型( 又は その配列)のとき,オブジェク
トには,省略時の初期化がなされる(
#
参照)
。
が
!
修飾付きの型のとき,その基礎と
するクラス型は,利用者宣言された省略時コンストラクタをもっていなければならない。
そうでないとき,生成されるオブジェクトの値は,不定とする。
が
!
修飾付きの型 又は
(
0
修飾付きでもよい)
"
互換のクラス型( 又は その配列)であって,
!
修飾付きの型の
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
((
メンバを( 直接 又は 間接に )もつならば ,そのプログラムは,不適格とする。
―
《生成初期化子》が
: ;
という形式の場合,値初期化がなされる(
#
参照)
。
―
《生成初期化子》が
:
《式並び》
;
という形式であって,
がクラス型の場合,
《式並び》を実引数と
して,適切なコンストラクタが呼び出される(
#
参照)
。
―
《生成初期化子》が
:
《式並び》
;
という形式であって,
が算術型,列挙型,ポインタ型,又は メ
ンバへのポインタ型であり,かつ 《式並び》が単一の式である場合,オブジェクトは,その式の( 必要な
らば変換された )値に初期化される(
#
参照)
。
―
いずれでもない場合,その《
<
式》は,不適格とする。
《
<
式》がクラス型のオブジェクト 又は その配列を作る場合,割付け関数,解放関数(
#
) 及び コンスト
ラクタ(
)に対し,アクセス制御 及び あいまい性制御が行われる。
《
<
式》がクラス型のオブジェクトの配列
を作る場合,デストラクタ(
)に対してもアクセス制御 及び あいまい性制御が行われる。
上で規定したオブジェクト初期化中のどこかで
例外を送出して終了した場合,適切な解放関数が見つかったと
きには,その解放関数が呼び出され,そのオブジェクトを構築しようとした記憶域を解放した後,その例外が《
<
式》の文脈で伝ぱ( 播)していく。あいまいなく合致する解放関数が見つからないときには,例外の伝ぱにおいて,
オブジェクトの記憶域の解放を実行しないことになる。
参考
呼び出された割付け関数が メモリを割り付けていない場合にはそれでよいが,そうでない場合には,結
果としてメモリリークが生じる。
《
<
式》が単項演算子
33
で始まる場合,解放関数名の検索は,大域的有効範囲で行われる。そうではない場合
であって,割付け型がクラス型
又は その配列である場合,解放関数名は,型
の有効範囲内で検索される。その
名前検索が失敗するか,又は 割付け型がクラス型 若しくは その配列でない場合,解放関数名は,大域的有効範囲内
で検索される。
位置指定解放関数の宣言が,位置指定割付け関数の宣言に合致する条件は,仮引数の個数が同じであって,仮引数
変換(
#
)を行った後で,第
仮引数を除くすべての型が同じになる場合とする。位置指定のない解放関数のすべ
ては,位置指定のない割付け関数に合致する。検索して一つだけの解放関数に合致した場合,その関数が呼び出され
る。そうでない場合,どの解放関数も呼び出されない。
《
<
式》が解放関数を呼び出すとき,割付け関数の返却値を,型
!
の第
実引数として渡す。位置指定解
放関数が呼び出されるとき,位置指定割付け関数に与えた付加的実引数の並びと同じもの,すなわち《生成位置指定》
構文で指定したのと同じ実引数の並びが渡される。処理系が割付け関数の呼出しの中でどの実引数のコピーを作る場
合も,
( 元と同じ値の )コピーを作って解放関数の呼出しに使ってもよいし ,割付け関数の呼出しの際に作ったコピー
を再利用してもよい。そのコピーをある場所で再利用しないとしても,別の場所でも再利用しないようにする必要は
ない。
割付け関数が,コンストラクタの実引数を評価する前に呼び出されるのか,コンストラクタの実引数を評価した後
でコンストラクタに入る前に呼び出されるかについては,未規定とする。割付け関数が空ポインタを返した場合,又
は 例外によって抜け出た場合に,コンストラクタの実引数を評価するか否かについても,未規定とする。
##
式
3
式は,
《
<
式》が作った最派生オブジェクト(
) 又は 配列を解体する。
3
式
3
33
キャスト式
33
S
T
キャスト式
第
の形式は,配列でないオブジェクト用とし,第
の形式は,配列用とする。演算対象の型は,ポインタ型 又は ポ
インタ型への単一の変換関数(
)をもつクラス型でなければならない。その結果の型は,
とする。
演算対象がクラス型の場合,演算対象がそのクラス型の単一の変換関数によってポインタ型に変換される。この
##
では,以後,その変換された演算対象を元の演算対象の代りに使うこととする。いずれの形式であっても,
の演算対象の値が空ポインタの場合,その演算の効果はない。第
の形式(オブジェクト用)の場合,
の演
算対象の値は,配列でないオブジェクト 又は 部分オブジェクト(
)へのポインタとし,そのようなオブジェクト
の基底クラスを表すもの(
)でなければならない。そうでない場合の動作は,未定義とする。第
の形式( 配列
用)の場合,
の演算対象の値は,その配列に対する先行した《
<
式》の結果のポインタ値でなければなら
ない
。そうでない場合の動作は,未定義とする。
注
それには《生成初期化子》の評価 及び/又は コンストラクタ呼出しを含んでいてもよい。
注
大きさがゼロでない配列の場合,この値は,
《
'
式》で作った配列の先頭要素を指すポインタと同じとする。大きさがゼロの配列は,
先頭要素をもたない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
()
参考
これは,
《
3
式》の構文は,
《
<
式》で割り付けたオブジェクトの型に合致しなければならないこと
を意味しており,
《
<
式》の構文に合致するのではない。
参考
!
付きの型へのポインタを,
《
3
式》の演算対象にしてもよい。
《
3
式》の演算対象とする前
に,そのポインタ式の定値性(
#
)をキャストで消す必要はない。
第
形式(オブジェクト用)において,演算対象の静的な型がその動的な型と異なる場合,その静的な型は,演算
対象の動的な型の基底クラスでなければならず,仮想デストラクタをもっていなければならない。そうでない場合の
動作は,未定義とする。第
形式( 配列用)において,オブジェクトの動的な型がその静的な型と異なる場合の動作
は,未定義とする。
《
3
式》内の《キャスト式》は,
回だけ評価する。
《
3
式》が処理系の解放関数(
)
)を呼び出し ,
《
3
式》の演算対象が空ポインタ定数でない場合,その解放関数は,ポインタが参照する記憶域を解放し,ポイン
タを無効にする。
参考
解放した記憶域を参照するポインタ値は,不定となる。
削除されるオブジェクトが削除時点で不完全な型であって,その完全クラスが自明でないデストラクタ 又は 解放
関数をもつ場合,その動作は,未定義とする。
《
3
式》は,削除されるオブジェクト 又は 配列要素に対するデストラクタが存在すれば ,それを呼び出す。
配列の場合,要素の解体は,アドレ スの降順に行われる( すなわち,そのコンストラクタの完了の逆順で行われる
(
(
参照)
。
《
3
式》は,解放関数(
)
)を呼び出す。
参考
処理系は,大域的解放関数として,非配列用の
(
)及び 配列用の
ST
(
)の省略時定義を提供している。
"##
プログラムは,これらの関数を代替する定
義(
)
) 及び/又は クラス固有の版(
#
)をもつことができる。
《
3
式》でキーワード
の前に単項演算子
33
が付いた場合,大域的解放関数が記憶域の解放に使われる。
解放関数 及び デストラクタの両方に対し ,アクセス制御 及び あいまい性制御を行う(
及び
#
参照)
。
#
明示的型変換(キャスト 記法)
:
《キャスト式》
;
という式の結果は,型
になる。
が参照型の場合,
結果は左辺値とし ,そうでない場合,結果は右辺値とする。
参考
がクラスでない
0
修飾型の場合,結果の右辺値の型を決定するときに,
0
修飾子は,無視される
(
参照)
。
明示的型変換は,関数形(
#
),型変換演算子(
,
,
及び
) 又は キャスト記法によって書くことができる。
キャスト式
3
単項式
型識別子
キャスト式
《キャスト式》の中で型を定義してはならない。
次の段落で規定していない型変換であって,利用者の明示的な定義がない型変換(
)は,不適格とする。
次のキャストで実行される変換は,いずれも明示的型変換のキャスト記法を使って実行することができる。
―
定値性キャスト(
#
)
―
静的キャスト(
#*
)
―
静的キャストに続く定値性キャスト
―
強制キャスト(
#
)
―
強制キャストに続く定値性キャスト
意味上の制約 及び 動作は,同じとする。明示的型変換が,上に示した変換のいくつかとして解釈できる場合,上方に
示してある側の変換として解釈する。そう解釈するとキャストが不適格となる場合であっても,その解釈を使う。あ
る変換が,静的キャストに続く定値性キャストという解釈のほかにも解釈できる場合,その明示的型変換は,不適格
とする。
例
6
QR&
<L
3
6
QR&
<+
3
6
QR&
#
3
<L
<+
QR&
6
!
#
!
Q
注
このことから,型
&
のオブジェクトはないので,型
&
のポインタを使ってオブジェクトを削除することはないといえる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
6!
&
''
不適格な静的キャストの解釈
R
キャスト記法を使ったキャストの演算対象は,型
:
不完全クラス型へのポインタ
;
の右辺値であってもよい。キャス
ト記法を使ったキャストの目的の型は,
:
不完全クラス型へのポインタ
;
であってもよい。その場合,継承関係が元の
クラスと目的のクラスとの間に存在したとしても,静的キャストとして解釈するか,強制キャストとして解釈するか
については,未規定とする。
これらの変換に加え,次にあげる静的キャスト 及び 強制キャストの演算(その後に定値性キャスト演算が続くこ
ともある。)は,その基底クラスの型がアクセスできない場合であっても,明示的型変換のキャスト記法を使って行っ
てもよい。
―
派生クラス型のオブジェクトへのポインタ 又は 派生クラス型の左辺値は,それぞれあいまいでない基底
クラス型へのポインタ 又は 参照に,明示的に変換してもよい。
―
派生クラス型のメンバへのポインタは,あいまいでなく仮想でない基底クラス型のメンバへのポインタに,
明示的に変換してもよい。
―
仮想でない基底クラス型のオブジェクトへのポインタ,仮想でない基底クラス型の左辺値 又は 仮想でな
い基底クラス型のメンバへのポインタは,それぞれ派生クラス型のポインタ,参照 又は メンバへのポ イ
ンタに,明示的に変換してもよい。
##
メンバポインタ演算子
メンバポインタ演算子
V!
及び
(!
は,左から右に結びついていく。
メンバポインタ式
3
キャスト式
メンバポインタ式
(!
キャスト式
メンバポインタ式
V!
キャスト式
項演算子
(!
は,第
演算対象(ここで
が完全定義されたクラス型であるとき,第
演算対象の型は,
:
のメ
ンバへのポインタ
;
でなければならない。)を,第
演算対象( 第
演算対象は,クラス
そのものであるか,
が
あいまいでなくアクセス可能な基底クラスになっているクラスでなければならない。)に結合する。結果は,第
演
算対象で指定された型のオブジェクト 又は 関数とする。
項演算子
V!
は,第
演算対象(ここで
が完全定義されたクラス型であるとき,第
演算対象の型は,
:
の
メンバへのポインタ
;
でなければならない。)を,第
演算対象( 第
演算対象は,型
:
へのポインタ
;
であるか,
:
があいまいでないアクセス可能な基底クラスとなっているクラスへのポインタ
;
でなければならない。)に結合す
る。その結果は,第
演算対象で指定された型のオブジェクト 又は 関数とする。
そのようなオブジェクトの動的な型が,そのポインタの参照するメンバをもたない場合,その動作は,未定義と
する。
0
修飾の制約 及び 演算対象の
0
修飾子を結び付けて結果の
0
修飾子を生成する方法は,
##
で規定した
8L(8+
の規則と同じとする。
参考
定値性クラスオブジェクトを変更するために,変更可能なメンバを参照しているメンバへのポインタを
使うことはできない。
例
F
Q
&
R&
F
&
F
:
:
!
%
0F33
&
''
は,
メンバ
F33
を参照する。
(!
%
NN
&
''
不適格:
は,定値オブジェクト
R
(!
又は
V!
の結果が関数の場合,その結果は,関数呼出し演算子
の演算対象としてしか使えない。
例
PPV!
P
P
L
.
&
この例では,
が指すオブジェクトがもつ,
の示すメンバ関数を呼び出す。
(!
式の結果は,第
演算対象が左辺値であり,第
演算対象がデータメンバへのポインタの場合に限り,左辺値とな
る。
V!
式の結果は,第
演算対象がデータメンバへのポインタの場合に限り,左辺値となる。第
演算対象が メン
バへの空ポインタ値(
)の場合,動作は未定義とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(*
#(
乗除演算子
乗除演算子
!
,
'
及び
U
は,左から右に結びついていく。
乗除式
3
メンバポインタ式
乗除式
!
メンバポインタ式
乗除式
'
メンバポインタ式
乗除式
U
メンバポインタ式
!
及び
'
の演算対象の型は,算術型 又は 列挙型でなければならない。
U
の演算対象の型は,汎整数型 又は 列挙
型でなければならない。通常の算術変換が,演算対象に対して行われ,結果の型が決まる。
項演算子
!
は,乗算を表す。
項演算子
'
は,商を生じ ,
項演算子
U
は,第
演算対象の第
演算対象による除算の剰余を生じる。
'
及び
U
の第
演算対象がゼロのときの動作は,未定義とする。そうでない場合,
' !
)
U
は,
と等しい。両方の演
算対象が負でない場合,その剰余は,負ではない。そうでない場合の剰余の符号は,処理系定義とする。
#)
加減演算子
加減演算子には
)
及び
V
があり,左から右に結びついていく。通常の算術変換が,算術型 又は 列
挙型の演算対象に対して行われる。
加減式:
乗除式
加減式
)
乗除式
加減式
V
乗除式
加算の場合,次のいずれかでなければならない。
―
両方の演算対象の型が,算術型 又は 列挙型である。
―
一方が完全に定義されたオブジェクト型へのポインタであって,他方が汎整数型 又は 列挙型のいずれか
になっている。
減算の場合,次のいずれかでなければならない。
―
両方の演算対象の型が,算術型 又は 列挙型である。
―
両方の演算対象が完全に定義された同じオブジェクト型への
0
修飾付きポインタ 又は
0
修飾なしポイン
タである。
―
左の演算対象が完全に定義されたオブジェクト型へのポインタであって,右の演算対象が汎整数型 又は 列
挙型である。
項演算子
)
の結果は,二つの演算対象の和とする。
項演算子
V
の結果は,第
演算対象から第
演算対象を減
じた結果とする。
これらの演算子においては,配列でないオブジェクトへのポインタは,配列要素の型としてそのオブジェクトの型
をもつ長さ
の配列の先頭要素へのポインタと同じ振る舞いをする。
あるポインタに汎整数型の式を加算する場合 又は あるポインタから汎整数型の式を減算する場合,その結果の型
は,そのポインタの型とする。そのポインタが,配列オブジェクトのある要素を指しており,配列が十分に大きい場
合,その結果は,結果の指す要素の添字と元の要素の添字との差分がその汎整数の式と等しくなるような隔たりの位
置にある要素を指すものとする。すなわち,式
がある配列オブジェクトの
"
番目の要素を指す場合,式
)A
( 又
は 等価の
A)
) 及び
VA
( ここで
A
の値は,
とする。)は,配列オブジェクトのそれぞれ
"
#
番目 及び
"
番目の要素(それらが存在すれば )を指すことになる。更に,式
が配列オブジェクトの最終要素を指してい
る場合,式
)L
は,その配列オブジェクトの最終要素の一つ先を指す。式
#
が配列オブジェクトの最終要素の一
つ先を指している場合,式
# VL
は,その配列オブジェクトの最終要素を指す。ポインタ演算対象 及び 結果が,と
もに同じ配列オブジェクトの要素 又は その最終要素の一つ先を指している場合,評価によってオーバフローを発生
させてはならない。そうでない場合の動作は,未定義とする。
同じ配列オブジェクトへの二つのポインタの減算をする場合,結果は,二つの配列要素を示す添字値の差分とする。
結果の型は,処理系定義の符号付き汎整数型とする。その型は,ヘッダ
(
)内の
で定義
された型と同じでなければならない。その他の算術オーバフローを伴う場合として,結果が提供された領域に入らな
い場合の動作は,未定義とする。すなわち,
及び
#
が,それぞれ配列オブジェクトの
"
番目と
番目の要素を指
している場合,式
V#
の値は,型
に適合する値
"
となる。更に,式
が配列オブジェクト内の
注
$
%
&!!
の改正版では,整数除算のアルゴ リズムは,
$
%
&!!
(プログラム言語
)
)の規定に従っている。そこでは,商
は,常にゼロに向かって丸められる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
要素 又は 最終要素の一つ先 を指し ,式
#
が同じ配列オブジェクトの最終要素を指している場合,
# )L
はその配
列オブジェクト内の要素を指さないが,
# )L V
の値は,
# V
)L
すなわち
V
V# )L
と同じ
値となり,式
が配列オブジェクトの最終要素の一つ先を指しているときにはゼロとなる。両方のポインタが同じ配
列オブジェクトの要素 又は 最終要素の一つ先を指していない場合の動作は,未定義とする。
この観点から,処理系は,
:
最終要素の一つ先
;
という要求を満たすために,オブジェクトの終点の後ろに
バイト
だけの余分(これが,プログラム内の他のオブジェクトと重なっていてもよい。)を必要とする。
#
シフト 演算子
シフト演算子
及び
は,左から右に結びついていく。
シフト式:
加減式
シフト式
加減式
シフト式
加減式
演算対象は,汎整数型 又は 列挙型でなければならず,汎整数昇格が行われる。結果の型は,左演算対象の昇格した
型とする。右演算対象の値が負のとき,又は 昇格した左演算対象のビット長と同じか大きいとき,その動作は,未定
義とする。
8L8+
の値は,
8L
を(ビットパタンとして解釈して)
8+
ビットだけ左にシフトさせ,残ったビットにゼロを埋め
た値とする。
8L
が符号なしの型の場合,結果の値は,
8L
に
の
8+
乗したものを乗じた値の,
G?BA:
@65)L
(
(
が
の場合) 又は
G<A
@65)L
(そうでない場合)を法とした剰余とする。
参考
定数
G?BA:
@65
及び
G<A
@65
は,ヘッダ
内に定義されている。
8L8+
の値は,
8L
を
8+
ビットだけ右にシフトして得られる値とする。
8L
が符号なしの型の場合,又は
8L
が符
号付きの型であって負でない値の場合,その結果の値は,
8L
を
の
8+
乗で割った商の整数部分とする。
8L
が符号付
きの型であって負の値の場合,結果の値は,処理系定義とする。
#*
関係演算子
関係演算子は,左から右に結びついていく。
例
は,
であって,
00
ではない。
関係式:
シフト式
関係式
シフト式
関係式
シフト式
関係式
%
シフト式
関係式
%
シフト式
演算対象の型は,算術型,列挙型,又は ポインタ型でなければならない。演算子
( 小なり),
( 大なり),
%
( 小なり 又は 等しい) 及び
%
( 大なり 又は 等しい)は,すべて
又は
を生じる。結果の型は,
%
型
とする。
算術型 又は 列挙型の二つの演算対象に対し ,通常の算術変換が行われる。二つのポインタ演算対象( 又は ポイン
タ 及び 空ポインタ定数)に対しては,それらを複合ポインタ型にするために,ポインタ変換(
) 又は 修飾変換
(
)が行われる。一方の演算対象が空ポインタ定数の場合,複合ポインタ型は,もう一方の演算対象の型とする。
そうでない場合,一方の演算対象が
:
へのポインタ
;
であって,もう一方が
:
へのポインタ
;
であると
き,その複合ポインタ型は,
:
へのポインタ
;
となる。ここで,
は,
及び
の和集合とする。そ
うでない場合,複合ポインタ型は,演算対象の一方の型と同類のポインタ型とし ,その
0
修飾情報は,二つの演算
対象の型の
0
修飾情報の和集合とする(
参照)
。
参考
すなわち,すべてのポインタは,空ポインタ定数と比較することができ,すべてのオブジェクトポイン
タは,
(
0
修飾付きでもよい )と比較することができる。
例
!&
!&
!!&
!
!&
注
ポインタ計算のもう一つの方式では,まずポインタを文字ポインタに変換する。その方式では,式の汎整数値を変換されたポインタに
加算する 又は それから減算する場合,まず元のポインタが指すオブジェクトの大きさを,その汎整数値に乗算する。そして,結果のポ
インタを,元のポインタの型に変換する。ポインタ減算の場合,文字ポインタの差分結果を,元のポインタが指すオブジェクトの大きさ
で除算する。ポインタ値にゼロを加算 又は 減算した場合,その結果は,元のポインタと同じとする。二つのポインタが同じオブジェク
トを指している場合,両ポインタがともに同じ配列の最終要素の一つ先を指している場合,又は 両ポインタとも空ポインタの場合,二
つのポインタの減算の結果は,型
&%%
に変換されたゼロとする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
Q
%
&
''
比較の前にともに
!
に変換される。
%
&
''
比較の前にともに
!
!
に変換される。
R
(ポインタ変換の後で )同じ型のオブジェクトへのポインタ 又は 関数へのポインタを比較することができ,次の結果
となる。
―
ポインタ
及び
が同じ型であり,同じオブジェクト 又は 関数を指している場合,同じ配列の最終要素
の一つ先を指している場合,又は ともに空ポインタの場合,
%
及び
%
は,
となり,
及び
は,
となる。
―
同じ型の
及び
が,異なるオブジェクト(ただし ,それらのオブジェクトは,ある同じオブジェクトの
メンバでもないし ,ある同じ配列の要素でもないとする。)を指している場合,別の関数を指している場
合,又は 一方だけが空ポインタの場合,
,
,
%
及び
%
の結果は,未規定とする。
―
二つのポインタが,ある同じオブジェクトの静的でないメンバを指している場合,又は そういうメンバの
部分オブジェクト 若しくは 配列要素を指している場合,さらにそれらが再帰的である場合,二つのメン
バがアクセス指定子ラベル(
)によって分離されていなくて,クラスが共用体でないときには,後で
宣言されたメンバへのポインタのほうが大きいとする。
―
二つのポインタが,ある同じオブジェクトの中の《アクセス指定子》のラベル(
)で分離されたデー
タメンバを指している場合の結果は,未規定とする。
―
二つのポインタが,ある同じ 共用体オブジェクトのデータメンバを指している場合,
( 必要ならば
!
に変換した後で )それらは等しい。二つのポインタが,ある同じ 配列の要素 又は 最終要素の一つ先を指
している場合,添字値の大きいオブジェクトへのポインタのほうが大きい。
―
その他のポインタ比較については,未規定とする。
#
等価演算子
等価式:
関係式
等価式
%%
関係式
等価式
[%
関係式
( 等しい)演算子
%%
及び ( 等しくない)演算子
[%
は,関係演算子と同じ意味規則の制約,変換 及び 結果の型
をもつが,演算子の優先順位( 低いこと ) 及び 真理値の結果だけは異なる。
参考
%%
は,
の真理値と
の真理値とが同じ場合に真となる。
同じ型のオブジェクト 又は 関数へのポインタは,
(ポインタ変換の後で )等価の比較ができる。同じ型の二つのポイン
タが等しくなるのは,両方とも空の場合,両方とも同じ関数を指している場合,又は 両方とも同じアドレス(
*
)
を指している場合であって,それらの場合に限る。
更に,メンバへのポインタど うし 又は メンバへのポ インタと空ポインタ定数とを比較することができる。メンバ
へのポインタ変換(
) 及び 修飾変換(
)が,それらのポインタを共通の型にするために実行される。一方の
演算対象が空ポインタ定数の場合,共通の型は,他方の演算対象の型とする。そうでない場合,共通の型は,演算対
象の一方の型と同類のメンバ型とし ,演算対象の型の
0
修飾の和集合を付けたものとする(
参照)
。
参考
すなわち,すべてのメンバへのポインタは,空ポインタ定数と比較することができる。
両方の演算対象が空の場合,比較結果は等しい。そうではなくて,一方だけが空の場合,比較結果は等しくない。そ
うでもなくて,ど ちらかが仮想メンバ関数の場合
,
結果は未規定とする。さらにそうでもない場合,メンバへのポ イ
ンタに対応するクラス型の仮想的なオブジェクトを用いて,それらの参照をはずしたとして,同じ最派生オブジェク
ト(
)の同じ メンバを指しているとき,又は 同じ部分オブジェクトを指しているとき,そのときに限り,比較結
果は等しい。
例
"
Q
&
R&
?
3
"
Q
R&
E
3
"
Q
R&
#
3
?
E
Q
R&
"33!
%
0"33&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
?33!
%
&
E33!
%
&
#33!
%
&
#33!
%
&
%
%%
&
''
偽となる。
#
ビット 積演算子
ビット積式
3
等価式
ビット積式
0
等価式
通常の算術変換を行う。結果は,両演算対象のビットごとの
&)*
とする。この演算子は,汎整数型 及び 列挙型
にだけ作用する。
#
ビット 差演算子
ビット差式
3
ビット積式
ビット差式
W
ビット積式
通常の算術変換を行う。結果は,両演算対象のビットごとの排他的
2B
とする。この演算子は,汎整数型 及び 列
挙型にだけ作用する。
#
ビット 和演算子
ビット和式:
ビット差式
ビット和式
1
ビット差式
通常の算術変換を行う。結果は,演算対象のビットごとの
2B
とする。この演算子は,汎整数型 及び 列挙型にだ
け作用する。
#
論理積演算子
論理積式
3
ビット和式
論理積式
00
ビット和式
演算子
00
は,左から右に結びつく。演算対象は,ともに
%
型に暗黙に変換する(
参照)
。結果は,両方の演
算対象が真の場合に真とし ,そうでない場合に偽とする。
0
とは異なり,
00
は,左から右への評価を保証する。第
演算対象は,第
演算対象が偽のときには評価しない。
結果は,
%
型とする。第
の式についてのすべての副作用は,一時変数の解体(
L+(+
)を除き,第
の式を評価
する前に発生する。
##
論理和演算子
論理和式:
論理積式
論理和式
11
論理積式
11
演算子は,左から右に結びつく。演算対象は,ともに
%
型に暗黙に変換する(
参照)。ど ちらか一方の演
算対象が真の場合,真を返し ,そうでない場合,偽を返す。
1
とは異なり,
11
は,左から右への評価を保証する。第
演算対象は,第
演算対象の評価が真のときには評価しない。
結果は,
%
型とする。第
の式についてのすべての副作用は,一時変数の解体(
)を除き,第
の式を評価
する前に発生する。
#(
二択条件演算子
二択条件式:
論理和式
論理和式
2
式
3
代入式
二択条件式は,右から左に結びつく。第
の式は,暗黙に
%
型に変換する(
参照)
。それが真と評価された場
合,条件式の結果は,第
の式の値とし ,そうでない場合は,第
の式の値とする。第
の式についてのすべての副
作用は,一時変数の解体(
)を除き,第
の式 又は 第
の式を評価する前に発生する。第
の式 又は 第
の
式のど ちらか一方だけを評価する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
第
演算対象 又は 第
演算対象のいずれかが,型
(
0
修飾付きでもよい。)の場合,左辺値から右辺値への
変換(
),配列からポインタへの変換(
) 及び 関数からポインタへの変換(
)を,第
演算対象 又は 第
演算対象に対して行う。その結果は,次のいずれかになる。
―
第
演算対象 又は 第
演算対象のど ちらか( 両方ではない)が,例外送出(
#
)となる。結果は,他
方の型の右辺値となる。
―
第
演算対象 及び 第
演算対象の両方が型
の場合,結果は,型
の右辺値となる。
参考
両方の演算対象が送出式という場合も,こうなる。
そうでない場合,第
演算対象 及び 第
演算対象が異なる型をもち,ど ちらかが(
0
修飾付きでもよい。)クラ
ス型の場合,それらの演算対象のそれぞれ一方を他方の型に変換しようとする。型
をもつ演算対象式
8L
が,型
をもつ演算対象式
8+
に合致するように変換できるか否かを決める手順を次に示す。
―
8+
が左辺値の場合,
8L
が暗黙の変換(
)によって型
:
への参照
;
に変換できるならば ,その参照が
直接
8L
に結合(
#
)しなければならないという制約を条件として,
8L
を
8+
に合致するように変換で
きる。
―
8+
が右辺値の場合 又は 上の変換ができない場合,次の手順とする。
8L
及び
8+
がクラス型をもち,その基礎とするクラス型が同じであるか,一方が他方の基底ク
ラスである場合,
のクラスが
のクラスと同じ型 又は その基底クラスであり,かつ
の
0
修飾が
の
0
修飾と同じかそれより多いとき,
8L
を
8+
に合致するように変換でき
る。この変換が適用されるとき,
8L
は,元のクラスオブジェクト( 又は それの適切な部分オ
ブジェクト )をまだ参照している型
の右辺値に変更される。
参考
すなわち,コピーは作られない。
そうでない場合(すなわち,
8L
又は
8+
がクラス型でない場合,又は 両方ともクラス型である
が,それらの基礎とするクラスが同じでないか,一方が他方の基底クラスでない場合),
8+
を
右辺値に変換したとすると
8+
がもつ型( 又は
8+
がすでに右辺値のときには,その型)に
8L
を暗黙に変換できるならば,
8L
を
8+
に合致するように変換できる。
ここで述べた手順によって,第
演算対象を第
演算対象に合致するように変換できるか否か,及び 第
演算対象を
第
演算対象に合致するように変換できるか否かが決まる。両方の変換ができる場合,又は 一つの変換が可能であっ
てもその変換があいまいな場合,そのプログラムは不適格とする。ど ちらの変換もできない場合には,両方の演算対
象の変更は行わず,更に次の検査を行う。一つだけの変換が可能な場合,その変換を選択された演算対象に対して実
行する。この
#(
の以後の部分では,こうして変換された演算対象を,元の演算対象の代りに用いる。
第
演算対象 及び 第
演算対象が左辺値であって同じ型である場合,結果は,その型の左辺値とする。
そうでない場合,結果は,右辺値とする。第
演算対象 及び 第
演算対象が同じ型ではなく,ど ちらかが(
0
修
飾付きでもよい。)クラス型である場合,それらの演算対象に適用すべき複数の変換(もしあれば )を決めるために
多重定義解決が利用される(
及び
(
参照)
。多重定義解決が失敗した場合,プログラムは不適格とする。
そうでなければ ,こうして決まった変換が適用される。この
#(
の以後の部分では,こうして変換された演算対象
を,元の演算対象代りに用いる。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
) 及び 関数からポインタへの標準
変換(
)を,第
演算対象 及び 第
演算対象に対して行う。その変換の後で,次のいずれかとなる。
―
第
演算対象 及び 第
演算対象が同じ型となっている。この場合,結果はその型とする。
―
第
演算対象 及び 第
演算対象が算術型 又は 列挙型となっている。この場合,通常の変換を行い,共通
の型にする。結果は,その型とする。
―
第
演算対象 及び 第
演算対象が,ともにポインタ型となっているか,一方がポインタ型で他方が空ポ
インタ定数となっている。この場合,ポインタ変換(
) 及び 修飾変換(
)を行い,それらをその
複合ポインタ型(
#*
)に変換する。結果は,その複合ポインタ型とする。
―
第
演算対象 及び 第
演算対象が,ともに メンバへのポインタ型となっているか,一方が メンバへのポ
インタ型で他方が空ポインタ定数となっている。この場合,メンバへのポインタ変換(
) 及び 修飾
変換(
)を行い,それらを共通の型に変換する。その
0
修飾は,第
演算対象 及び 第
演算対象に
合致しなければならない。結果は,その共通の型とする。
#)
代入演算子
いくつかの代入演算子があり,それらのすべてが右から左に結びついていく。すべての代入演算
子について,左の演算対象は,変更可能な左辺値でなければならない。代入式の型は,左の演算対象の型とする。代
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
入演算の結果は,代入が行われた後の左の演算対象に格納された値とする。結果は,左辺値とする。
代入式
3
二択条件式
論理和式
代入演算子
代入式
送出式
代入演算子
3
次のいずれか
%
!%
'%
U%
)%
V%
%
%
0%
W%
1%
単純代入(
%
)の場合,左の演算対象の参照オブジェクトの値を右の式の値に置き換える。
左の演算対象がクラス型でない場合,右の式は,左の演算対象の
0
修飾なしの型に暗黙に変換する(
参照)
。
左の演算対象がクラス型の場合,そのクラスは,完全でなければならない。クラスの各オブジェクトへの代入は,
コピー代入演算子の定義に従う(
及び
#
参照)
。
参考
クラスオブジェクトの場合,一般的には,代入は,初期化と同じではない(
#
,
,
(
及び
参照)
。
代入演算子の左の演算対象が
を参照しているとき,演算は,その参照が表す型
のオブジェクトへの代入と
なる。
8L
$%
8+
という形の式の挙動は,
8L
の評価が
回しか行われないことを除き,
8L
%
8L
$
8+
と同じとする。
)%
及び
V%
の場合,
8L
の型が算術型であるか,
8L
が(
0
修飾付きでもよい。)完全に定義されたオブジェクトへのポイ
ンタであるかのど ちらかでなければならない。その他のすべての代入演算子の場合には,
8L
の型は,算術型でなけれ
ばならない。
オブジェクトに格納される値が,そのオブジェクトの記憶域と何らかの形で重なっている他のオブジェクトからア
クセスされる場合,完全に重なり合っていて,かつ二つのオブジェクトの型が同じでなければならない。そうでない
場合の動作は,未定義とする。
#
コンマ演算子
コンマ演算子は,左から右に結びつく。
式:
代入式
式
代入式
コンマで分離した二つの式を,左から右に評価し ,左の式の値を捨てる。左辺値から右辺値への標準変換(
),配
列からポインタへの標準変換(
) 及び 関数からポインタへの標準変換(
)は,左の式に適用しない。左の式
についてのすべての副作用は,一時変数の解体(
)を除き,右の式を評価する前に発生する。結果の型 及び 値
は,右の演算対象の型 及び 値とする。右の演算対象が左辺値の場合,結果は左辺値とする。
コンマが特殊な意味をもつ文脈[ 例えば ,関数の実引数並び(
#
)の中 及び 初期化子の並び(
#
)の中]の
場合,この箇条で規定するコンマ演算子は,括弧の中にだけ書くことができる。
例
%*
)+
&
この例は,三つの実引数をもち,第
実引数の値は,
となる。
#*
定数式
"##
では,いくつかの場所で,汎整数 又は 列挙体の定数に評価される式が要求される。その場所
は,配列上限(
及び
#
),
!
式(
(
),ビットフィールド 長(
*(
),列挙子初期化子(
)
),静的メ
ンバ初期化子(
*
), 及び 汎整数 又は 列挙体の非型のテンプレート実引数(
)とする。
定数式:
二択条件式
汎整数の《定数式》内に書くことができるのは,次に挙げるものだけとする。
―
リテラル(
)
―
列挙子
―
定数式によって初期化された汎整数型 又は 列挙型をもつ,
!
属性の変数 又は 静的データメンバ(
#
参照)
―
汎整数型 又は 列挙型をもつ非型のテンプレート仮引数
―
!J
式
浮動小数点リテラル(
)が現れるのは,それらが汎整数型 又は 列挙型にキャストされる場合だけとする。汎
整数型 又は 列挙型への型変換だけが使用できる。特に,
!J
式の中を除き,関数,クラスオブジェクト,ポインタ
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)#
又は 参照を使ってはならず,代入演算子,増加演算子,減少演算子,関数呼出し 又は コンマ演算子を使ってはなら
ない。
他の式が《定数式》とみなされるのは,局所的でない静的オブジェクトの初期化(
(
)の場合だけとする。その
場合の《定数式》は,評価した結果が次のいずれかでなければならない。
―
空ポインタ値(
参照)
―
空メンバポインタ値(
参照)
―
算術定数式
―
アドレス定数式
―
参照定数式
―
完全オブジェクト型に対するアドレス定数式と汎整数定数式との加算 又は 減算
―
メンバポインタ定数式
算術定数式は,汎整数の《定数式》の要件を満たさなければならない。ただし ,次の二つは許される。
―
浮動小数点リテラルは,汎整数型 又は 列挙型にキャストしなくてもよい。
―
浮動小数点型への変換をしてもよい。
アドレス定数式は,静的記憶域期間をもつオブジェクト,文字列リテラル(
) 又は 関数のいずれかを表す
左辺値へのポインタとする。そのポインタは,明示的に単項演算子
0
を使うか,暗黙にポインタ型の非型のテンプ
レート仮引数を使うか,又は 配列型(
) 若しくは 関数型(
)の式を使うかして作る。添字付け演算子
ST
及
び クラスメンバアクセス演算子(
(
及び
V
),単項演算子の
0
及び
!
,並びに ポインタのキャスト( 動的キャスト
(
#)
)を除く。)は,アドレス定数式を作るのに使用できるが,オブジェクトの値をこれらの演算子を使ってアクセ
スしてはならない。添字付け演算子を使うとき,その演算対象の一つは,汎整数定数式としなければならない。
"
互
換でないクラスオブジェクト(
*
)の部分オブジェクトのアドレスを示す式は,アドレス定数式としない。関数が イ
ンラインであって参照型を返す場合であっても,その関数の呼出しをアドレス定数式に使ってはならない。
参照定数式は,静的記憶期間をもつオブジェクト,非型テンプレートの参照型の仮引数 又は 関数を指す左辺値と
する。添字付け演算子
ST
,クラスメンバアクセス演算子(
(
及び
V
),単項演算子の
0
及び
!
,並びに 参照キャス
ト[ユーザ定義変換関数(
)を呼び出す場合 及び 動的キャスト(
#)
)を除く。]は,参照定数式を作るの
に使用できるが,あるオブジェクトの値をこれらの演算子を使ってアクセスしてはならない。添字付け演算子を使う
場合,その演算対象の一つは,汎整数定数式としなければならない。
"
互換でないクラスオブジェクト(
*
)の基底
クラス 又は メンバを指す左辺値式は,参照定数式としない(
)
参照)
。関数呼出しは,その関数が インラインで
あって参照型を返す場合であっても,それを参照定数式に使ってはならない。
メンバ先ポインタ定数式は,修飾付き識別子の演算対象(
#
)に単項演算子
0
を作用させて作る。この場合,そ
の演算対象の前にメンバへのポインタのキャスト(
#*
)を置いてもよい。
(
文
特に規定しない限り,文は,順に実行される。文の種類は,次のとおりとする。
文
3
ラベル付き文
式文
複合文
選択文
繰返し文
飛越し文
宣言文
監視ブロック
(
ラベル付き文
文には,ラベルを付けることができる。
ラベル付き文
3
識別子
3
文
定数式
3
文
3
文
識別子のラベルは,その識別子を宣言する。識別子のラベルは,
の目標としてだけに使う。ラベルの有効範囲
は,それが出現した関数の中とする。ラベルを関数内で再宣言してはならない。ラベルは,その定義の前にある
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)(
文で使ってもよい。ラベルは,それ自身の名前空間をもち,他の識別子との干渉はない。
!
ラベル 及び
3
ラベルは,
!<
文の中にしか使ってはならない。
(
式文
式文の形式は,次のとおりとする。
式文
3
式
&
《式》を評価し ,その結果を捨てる。
《式文》の《式》には,左辺値から右辺値への標準変換(
),配列からポイン
タへの標準変換(
) 及び 関数からポインタへの標準変換(
)を適用しない。すべての式文の副作用は,その
次の文の実行開始前に完了する。
《式》のない《式文》を,空文と呼ぶ。
参考
文のほとんどは,式文( 通常は,代入 又は 関数呼出し )となる。空文は,複合文の終了を示す
の直
前にラベルを置くのに役立ち,
<
文(
(#
)のような繰返し文に空の本体を置くのにも役立つ。
(
複合文(ブロック)
単一の文が想定されている場所に複数の文を書けるようにするために,複合文(いわゆる
:
ブロック
;
と同じ 。)がある。文列の文は,特に規定しない限り,その現れた順に実行する。
複合文
3
文列
文列
3
文
文列
文
《複合文》は,局所的有効範囲を定める(
参照)
。
参考
文の一種に,宣言がある(
()
参照)
。
(
選択文
選択文は,いくつかの制御の流れのうち,いずれか一つを選択する。
選択文
3
条件
文
条件
文
文
条件
文
条件
3
式
型指定子列
宣言子
%
代入式
(
では,副文という用語を用いて,構文規則の中に現れる単一の文 又は 複数の文を表す。
《選択文》の中の副文(
文の
!
形式における二つの文の場合,それぞれの副文)は,暗黙に局所的有効範囲を定める(
参照)。選択文
中の副文が単一の文であって複合文ではない場合,元の副文を,単一の文から成る文列を波括弧でくくってできる複
合文に書き変えたとして扱う。
例
&
この例は,次のように書き換えることができる。
Q
&
R
したがって,
文の後では,
は,もはや有効でない。
《条件》に対する規則は,
《選択文》だけでなく,
文 及び
<
文にも適用される(
(#
参照)
。
《条件》の中の
《宣言子》には,関数 又は 配列を指定してはならない。
《型指定子列》には,
を含めてはならず,新たなク
ラス 又は 列挙体を宣言してはならない。
《条件》の中の一種の宣言によって導入した名前(《条件》の中の《型指定子列》 又は 《宣言子》によって導入し
た名前)の有効範囲は,それを宣言した位置から,その条件が制御する副文の終了の位置までとする。そういう名前
が,その条件が制御している副文の中の最外側ブロックで再宣言された場合,その名前を再宣言した宣言は,不適格
とする。
例
%
Q
&
''
不適格,
の再宣言
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
))
Q
&
''
不適格,
の再宣言
R
!<
文ではない文において,
《条件》が初期化をもつ宣言となっている場合,その値は,宣言された変数の値を
暗黙に
%
型に変換した値とする。その変換が不適格な場合,そのプログラムは不適格とする。
!<
文において,
《条件》が初期化をもつ宣言となっている場合,その値は,宣言された変数が汎整数型 又は 列挙体型のときには,そ
の変数の値とし ,そうでないときには,汎整数 又は 列挙体に暗黙に変換された変数の値とする。
《条件》が《式》の
場合には,その値は,その《式》の値とするが,
!<
文を除く文においては,
%
型に暗黙に変換した値とする。
その変換が不適格な場合,そのプログラムは不適格とする。
《条件》の値のことを,あいまいな使い方でない場所で
は,単に
:
条件
;
という。
《条件》が,構文上,
《式》とも 局所的名前の宣言とも解釈できる場合,宣言と解釈する。
(
"
文
条件(
(
)が
の場合,第
の副文が実行される。
《選択文》が
!
部をもち,
《条件》が
の場合,第
の副文が実行される。
文が第
の形式(
を含む形式)であって,第
の副文も
文とした場合,
その内側の
文には,
部を付けなければならない。
(
+
&
文
!<
文は,
《条件》の値に応じて,複数の文の中から一つを選んでそこに制御を移す。
《条件》の型は,汎整数型,列挙体型 又は 単一の変換関数によって汎整数型 若しくは 列挙型になるクラス型(
)
のいずれかでなければならない。
《条件》がクラス型の場合,その変換関数を呼び出して変換する。
(
では,その
変換結果を元の条件の代りとして使う。汎整数昇格を,実行する。
!<
文中のすべての文は,次の形式の
!
ラ
ベルを一つ以上もつことができる。
定数式
3
ここで,
《定数式》は,汎整数の《定数式》でなければならない。汎整数の《定数式》
(
#*
)は,
!<
文の《条件》
の昇格後の型に暗黙に変換する。同じ
!<
文内では,どの二つの
!
定数をとっても,その値が
!<
文の《条
件》の昇格後の型に変換したときに同じであってはならない。
一つの
!<
文の中には,次の形式のラベルは,高々一つでなければならない。
3
複数の
!<
文を,入れ子にしてもよい。その場合,
!
ラベル 又は
3
ラベルは,それを囲む最小の
!<
文に結び付く。
!<
文の実行では,その《条件》を評価し,それぞれの
!
定数の値と比較する。ある
!
定数の値が《条件》
の値と同じ 場合,その一致した
!
ラベルが付いた文に制御を移す。ど の
!
定数も《条件》と一致しない場合,
3
ラベルがあるときには,
3
ラベルの付いた文に制御を移し ,
3
ラベルがないときには,
!<
文
中のどの文も実行せずに
!<
文の実行を終える。
!
ラベル 及び
3
ラベル自体は,制御の流れを変えない。制御の流れは,それらのラベルをまたいで続いて
いく。
!<
文からの飛出しについては,
((
の
%I
文に規定する。
参考
通常,
!<
文を構成する副文は,複合文となっており,
!
ラベル 及び
3
ラベルは,その副
文( 複合文)中の最上位の文に現れるが,これは必要条件ではない。宣言を,
!<
文の副文内に書いて
もよい。
(#
繰返し文
繰返し文は,ループ実行を指定する。
繰返し文
3
条件
文
文
式
&
初期化文
条件
&
式
文
初期化文
3
式文
単純宣言
参考
《
初期化文》は,セミコロンで終了する。
《繰返し文》中の副文は,局所的有効範囲(
)を暗黙に定める。その範囲は,そのループ実行の各回ごとに入っ
てから出るまでの範囲とする。
注
すなわち,
は,最も近い
のない
%
と結び付く。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
《繰返し文》の副文が単一の文であって複合文でない場合,元の単一の文から成る文列を波括弧でくくってできる
複合文に書き換えたとして扱う。
例
VV
%
.
&
この例は,次のように書き換えたものと同じになる。
VV
%
.
Q
&
R
したがって,
は,
<
文の後では有効でない。
参考
《繰返し文》の中の《条件》に対する要件は,
(
に規定している。
(#
+&
文
<
文では,
《条件》の値(
(
)が
!
になるまで,その副文を繰り返して実行する。その検査
は,副文の実行前に毎回行う。
<
文の《条件》が《宣言》である場合,宣言された変数の有効範囲は,その宣言地点から
<
文の終わりま
でとする。
%
文
この形式の
<
文は,次と同じとする。
3
Q
''
条件の有効範囲の始まり
%
&
Q
文
&
R
R
''
条件の有効範囲の終わり
《条件》の中で作られたオブジェクトは,ループの繰返しごとに解体する。
例
6
Q
&
6
3
Q
R
X6
Q
R
Q
[%
.&
R
R&
%
L&
6
%
Q
''(((
%
.&
R
この
<
ループでは,コンストラクタ 及び デストラクタがそれぞれ
回ずつ呼び出される。
回目
では《条件》が成功し ,
回目では 《条件》が失敗する。
(#
文
3
文の中の《式》は,暗黙に
に変換する。それができない場合,そのプログラムは不適格とする。
3
文は,
《式》が
!
になるまで,副文を繰り返し実行する。その検査は,副文の実行の後で毎回行う。
(#
"
文
文の形式は,次のとおりとする。
初期化文
条件
&
式
文
この
文の形式は,次の形式と同じとする。
Q
初期化文
条件
Q
文
式
&
R
R
ただし ,次の違いがある。
―
《
初期化文》内で宣言された名前は,
《条件》で宣言された名前と同じ宣言領域にある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)*
―
( 別の繰返し文によって囲まれてはいない)
《文》の中の
(
((
)は,
《式》を実行して《条件》
の再評価にただちに制御を移す。
参考
したがって,第
の文は,ループの初期化を指定し,
《条件》
(
(
)は,各繰返しの実行前に行われる検
査を指定する。
《条件》が
になると,ループから抜け出る。
《式》は,各繰返しの実行後に行われる
増加を指定することが多い。
《条件》 及び 《式》の,いずれか一方 又は 両方を省略してもよい。
《条件》がない場合,対応する
<
文表記
を
としたものに等価とする。
《
初期化文》が宣言である場合,宣言された名前の有効範囲は,
《
文》の最後までとする。
例
%
M+&
SL.T&
%
.&
L.&
))
ST
%
&
%
&
''
は,
M+
となる。
((
飛越し文
飛越し文は,無条件に制御を移す。
飛越し文
3
&
&
式
&
識別子
&
ある有効範囲からの飛出しの時点(ただし ,有効範囲は終わっている。)では,その有効範囲内で宣言されて構築
された自動記憶域期間(
)
)をもつすべてのオブジェクト( 名前付きオブジェクト 又は 一時変数)に対応するデ
ストラクタ(
)を,それらの宣言の逆順に呼び出す。ループの外への制御の移動,ブロックの外への制御の移動
又は そのブロック内で自動記憶域期間をもつ初期化変数の宣言地点の前に戻る移動においては,制御が移動した時点
では有効範囲にあるが,移動先では有効範囲にはない自動記憶域期間をもつ変数を解体する(ブロックの中への制御
の移動については,
()
で規定する。)
。
参考
ただし,プログラムは,
( 例えば,
(
?
又は
%
の呼出し(
)によって,
)自動記憶域期間をも
つクラスオブジェクトを解体せずに終了することもある。
((
%.
文
%I
文は,
《繰返し文》 又は
!<
文の中にしか現れてはならず,それを最小に取り囲む《繰返
し文》 又は
!<
文を終了させる。その終了させた文に続く文( 存在すれば )に,制御を移す。
((
文
文は,
《繰返し文》の中にしか現れてはならず,そのループを最小に取り囲む《繰返し
文》のループ 継続処理の部分,すなわちループの末端部に制御を移す。より正確にいえば ,次のそれぞれの文につい
て,
文が別の《繰返し文》の中に入っていない場合,
と同等とする。
Q
Q
&
&
Q
Q
Q
Q
''
(((
''
(((
''(((
R
R
R
3
&
3
&
3
&
R
R
&
R
((
文
関数は,
文によって呼出し元に戻る。
《式》のない
文は,値を返さない関数にだけ使うことができる。すなわち,
0
3
型を返す関数,コンストラ
クタ(
),デストラクタ(
)のいずれかでだけ使うことができる。
0
3
でない型の《式》をもつ
文
は,値を返す関数でだけ使うことができ,その《式》の値が関数の呼出し元に渡される。その《式》は,それが現れ
る関数の返却値の型に,暗黙に変換される。
文は,一時的オブジェクト(
)の構築 及び コピーを伴うこ
とがある。関数の終点からはずれ出てしまうことは,値なしの
文がある場合と同等とする。それが,値を返す
関数で発生した場合の挙動は,末定とする。
型
:
;
の《式》をもつ
文は,返却値の型が
の関数においてだけ使うことができる。
《式》の
評価は,関数が呼出し元に戻る直前に行う。
((
文
文は,その《識別子》のラベルが付いた文に,無条件で制御を移す。その《識別子》は,その
時点の関数の中に存在するラベル(
(
)でなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
()
宣言文
一つの宣言文は,一つ以上の新しい識別子をブロック内に導入する。形式は,次のとおりとする。
宣言文
3
ブロック宣言
ある宣言によってブロックに導入された識別子が,その外側のブロックですでに宣言されている場合,外側の宣言は,
内側ブロックの残りの部分では隠ぺいされ,内側ブロックの終了後に再びその効力を現わす。
自動記憶域期間(
)
)をもつ変数は,その変数の《宣言文》を実行するたびに初期化する。ブロック内で宣言さ
れた自動記憶域期間をもつ変数は,そのブロックから出るときに解体する(
((
参照)
。
ブロックの中に飛び込むことは可能であるが,初期化をもつ《宣言》を迂回して飛び込むことはできない。自動記
憶域期間をもつある局所変数が有効範囲にない場所から,その有効範囲になっている場所への飛越し
があるプロ
グラムは,その変数が
"
互換型(
*
)であって《初期化子》
(
#
)をもたずに宣言されている場合を除き,不適格
とする。
例
Q
''(((
&
''
不適格
3
の有効範囲内への飛越し
''(((
3
5
%
L&
''(((
3
&
''
この飛越しは,
B>
。この飛越しが,
のデストラクタを
''
呼び出すことになり,再びラベル
の直後で構築される。
R
静的記憶域期間(
)
)をもつすべての局所オブジェクトは,そのゼロ初期化(
#
)を,その他のすべての初期
化が起きる前に実行する。静的記憶域期間をもつ
"
互換型(
*
)の局所オブジェクトの定数式による初期化は,初
めてそのブロックに入る前に行う。処理系は,名前空間有効範囲(
(
)内の静的記憶域期間をもつオブジェクトを
静的に初期化することが許されているが,それと同じ条件で,静的記憶域期間をもつ他の局所オブジェクトを早期に
初期化してよい。そうしない場合,そのようなオブジェクトの初期化は,その宣言に初めて制御が渡った時点で行わ
れる。そのようなオブジェクトは,初期化が完了した時点で,初期化されたことになる。初期化が例外を送出して抜
け出てしまった場合,初期化は未完了とし ,その宣言に再度制御が渡った時点で再試行する。オブジェクトを初期化
している間に,制御がその宣言に( 再帰的に )再度渡った場合の挙動は,未定義とする。
例
Q
%
+! &
''
再帰的呼出しであり,動作は未定義。
)L&
R
静的記憶域期間をもつ局所オブジェクトのデストラクタは,そのオブジェクトが構築された場合にだけ実行する。
参考
静的記憶域期間をもつ局所オブジェクトが解体される順序については,
(
に規定する。
(
あいまい性の解決
《式文》 及び 《宣言》を含む文法には,あいまい性がある。左端の部分式に関数形の明示
的型変換(
#
)をもつ《式文》は,最初の《宣言子》が
で始まる《宣言》と区別できないことがある。この場
合のその《文》は,
《宣言》とする。
参考
あいまい性を解決するには,それが《式文》なのか《宣言》なのかを決めるために《文》の全体を調べ
ることが必要となるかもしれない。それによって,多くのあいまい性が解決される。
例
を《単純型指定子》
(
)#
)とする。
V
%
,&
''
これは式文
))&
''
これは式文
/ &
''
これは式文
! &
''
これは宣言
S/T&
''
これは宣言
%
Q
L
+
R&
''
これは宣言
! * &
''
これは宣言
注
'"
文の《条件》から
"
ラベルへの制御の移動も,この意味からいって,飛越しと考える。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
この最後の例では,
は,
へのポインタであり,それを
*
で初期化している。もちろ
ん,この例は,意味規則からは不適格となるが,そのことは,構文規則の解析には影響しない。
次の例は,すべて《宣言》となる。
例
Q
''(((
3
&
&
,
&
R&
&
''
宣言
!
&
''
宣言
%
,&
''
宣言
,
,
%*&
''
宣言
&
,
+ &
''
宣言
あいまい性の解決は,純粋に構文規則上のこととする。すなわち,ある文の中にある名前の意味は,それが《型名》
であってもなくても,一般的にいって,あいまい性の解決には使えないし ,あいまい性の解決によって変わらない。
クラステンプレートは,修飾付き名前が《型名》であるか否かを決めるために,必要に応じて具現化される。あいま
い性の解決は,文法解析処理
1!
に先行し ,あいまい性が解決されて宣言とされた文が,不適格な宣言となる
こともある。文法解析処理中に,テンプレート仮引数の名前の結合が,試行の文法解析のときの結合と異なってきた
場合,そのプログラムは,不適格とする。診断は,不要とする。
参考
これは,その名前がその宣言のはじめのほうで宣言されている場合にだけ発生し うる。
例
L
Q
L
Q
L &
R
%
Q
&
R
L
Q
R
R&
+
Q
+
Q
R
R&
!! +
&
Q
''
あいまい性の解決からは,これは宣言であると文法解析される。
L
%
*
+M
''
+
は,
L
型の変数として宣言される。
!! +
&
''
しかし ,この宣言の最後の部分では
''
文法解析不可能となる。それは,
+
が
''
型名であることに依存するからである。
R
)
宣言
宣言は,名前をど う解釈すべきかを指定する。宣言の形式は,次のとおりとする。
宣言列
3
宣言
宣言列
宣言
宣言
3
ブロック宣言
関数定義
テンプレート宣言
明示的具現化
明示的特殊化
結合指定
名前空間定義
ブロック宣言
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
単純宣言
!
定義
名前空間別名定義
!
宣言
!
指令
単純宣言
3
宣言指定子列
初期化宣言子並び
&
参考
《
!
定義》は
)
で規定し,
《結合指定》は
)#
で規定する。
《関数定義》は
で規定し,
《テンプレー
ト宣言》は
で規定する。
《名前空間定義》は
)
で規定し ,
《
!
宣言》は
)
で,
《
!
指令》
は
)
で規定する。
《単純宣言》は,
《宣言指定子列》 及び 《初期化宣言子並び》の二つの部分に分かれる。
《宣言指定子列》を構成する
《宣言指定子》については
)
で規定し ,
《初期化宣言子並び》を構成する《宣言子》については
で規定する。
《宣言》は,ある有効範囲(
)の中に現れる。有効範囲の規則は,
で規定する。関数を宣言している宣言,
又は クラス,テンプレート 若しくは 関数を定義している宣言は,その中に
重以上に入れ子になった有効範囲をも
つ。これらの入れ子になった有効範囲は,更にその中に宣言を入れ子にすることができる。この
)
において,
を
宣言 又は 宣言の部分構成要素とし ,
を構成要素として,次の書き方をしたときは,いずれも,その宣言の直接の
構成要素
だけを意味し ,入れ子になった内側の宣言の構成要素は意味しない。
―
の
―
の中の
―
に含まれる
《単純宣言》において,省略可能な《初期化宣言子並び》が実際に省略できるのは,クラス(
*
)又は 列挙体(
)
)
を宣言する場合だけ,すなわち,
《宣言指定子列》に,
《クラス指定子》,
《クラスキー》
(
*
)付き《詳述型指定子》 又
は 《列挙体指定子》のいずれか一つが含まれる場合だけとする。これらの場合,及び 《クラス指定子》 又は 《列挙
体指定子》が《宣言指定子列》に存在する場合,その指定子の中の《識別子》は,その《宣言》によって宣言される
名前( 構文規則に従って,
《クラス名》,
《列挙体名》 又は 《列挙子》のいずれか )の一つとなる。こうした場合,無
名のビットフィールド(
*(
)を宣言するときを除いて,その《宣言指定子列》は,プログラムに一つ以上の名前を新
たに導入するか,以前の宣言で導入した名前を再度宣言し直すかのいずれかでなければならない。
例
Q
R&
''
不適格
Q
R&
''
不適格
《初期化宣言子並び》中の《初期化宣言子》は,それぞれ,
《宣言子識別子》を一つだけもつ。この《宣言子識別子》
が,その《初期化宣言子》によって宣言される名前となり,したがって,その《宣言》によって宣言される名前の一
つともなる。
《宣言指定子列》中の《型指定子》
(
)#
)と,
《初期化宣言子》中の再帰的な《宣言子》の構造とによっ
て,一つの型(
)が指定される。この型が,
《初期化宣言子》の宣言する名前に結び付けられる。
《宣言指定子列》に
1
3
指定子がある場合,その宣言は,型定義宣言と呼ぶ。その《初期化宣言子》の名前は,
それぞれ《型定義名》として宣言され,それに結び付けられる型の同義語になる(
)
参照)
。
《宣言指定子列》に
1
3
指定子がない場合,その宣言を,その名前に結び付けられる型が関数型(
#
)のとき関数宣言と呼び,そ
うでないときオブジェクト宣言と呼ぶ。
関数宣言は,宣言一般には現れえない構文要素を書き加えて初めて関数定義となる。しかし,オブジェクト宣言は,
それ自身で定義ともなる。ただし ,次の二つの条件の両方を満たす場合を除く。
―
?
指定子を含んでいる
―
初期化子(
)をもたない
定義を行うと,適切な量の記憶域が割り付けられ,適切な初期化(
#
)が行われる。
《宣言指定子列》を省略してもよいのは,コンストラクタ,デストラクタ 及び 型変換の関数宣言だけとする。
)
指定子
《宣言》の中で使える指定子は,次のとおりとする。
宣言指定子
3
記憶域種別指定子
型指定子
注
言語の
暗黙の
の規則は,
では許されていない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
関数指定子
宣言指定子列
3
宣言指定子列
宣言指定子
《宣言指定子》の最長の列が,
《宣言》の《宣言指定子列》とみなされる。それが型名一つだけのこともある。この
列は,自己矛盾していてはならない。
( 自己矛盾していないことの定義は,
)
〜
)#
による。)
例
!
C&
C&
''
エラー
3
名前がない。
ここで,宣言
C
は,型
C
の静的変数の名前が指定されていないので,不適格となる。
C
とい
う変数を得たければ ,
(
,
以外の)
《型指定子》を書いて,その《型定義名》
C
が( 再)宣
言される名前であって,
《宣言指定子》の列の一部ではないことを示しておかなければならない。もう一つ
の例を,次に示す。
C &
''
!
となり,
''
!
にはならない。
C &
''
これは,
となる。
参考
,,
及び
は,特に指定しなければ,
を指定したことになるので,それら
の指定子の直後に現れる《型名》は,宣言 又は 再宣言される名前として扱われる。
例
C &
''
となる。
C &
''
となる。
)
記憶域種別指定子
記憶域種別指定子は,次のとおりとする。
記憶域種別指定子
3
《記憶域種別指定子》は,一つの《宣言指定子列》の中に高々一回しか現れてはならない。
《記憶域種別指定子》が《宣
言指定子列》に現れる場合,その《宣言指定子列》の中に
1
3
指定子があってはならず,その宣言の《初期化宣言
子並び》が空であってはならない。ただし ,大域的な無名の共用体で,
として宣言されるものは除く(
*#
参
照)
。
《記憶域種別指定子》は,それぞれの《初期化宣言子》で宣言される名前に適用され,その他の指定子によって
宣言される名前には適用されない。
《記憶域種別指定子》は,明示的特殊化(
)
) 又は 明示的具現化(
)
)
の指令の中に指定してはならない。
指定子 又は
!
指定子は,ブロック(
(
) 又は 関数仮引数(
)内で宣言されるオブジェクトの名前
にだけ適用することができる。これらは,名前付きオブジェクトが自動記憶域期間(
)
)をもつことを指定する。
ブロック有効範囲で《記憶域種別指定子》を伴わずに宣言されるオブジェクト,又は 関数仮引数として宣言されるオ
ブジェクトの記憶域期間は,自動記憶域期間とする。
参考
したがって,
指定子は,ほとんど すべての場合に冗長となり,あまり使われない。
には,
《宣
言文》を《式文》から明確に区別するために使うという使い方がある(
(
参照)
。
!
指定子は,
指定子と同じ 意味をもつ。ただし ,指定したオブジェクトの使用頻度が高い可能性がある
という情報を,処理系に与える。
参考
処理系は,この情報を無視してもよい。そのオブジェクトのアドレスを使っているプログラムについて
は,多くの処理系がこの情報を無視している。
!
指定子は,オブジェクト名,関数名 及び 無名の共用体(
*#
)にだけ適用することができる。ブロック中に
の関数宣言があってはならないし ,関数の仮引数に
を指定してはならない。オブジェクトの宣言にお
ける
!
指定子は,そのオブジェクトが静的記憶域期間(
)
)をもつことを宣言する。
!
指定子は,クラス
メンバの宣言に使うこともできる。その効果は
*
で規定する。
!
指定子付きで宣言された名前の結合について
は,
#
で規定する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
?
指定子は,オブジェクト 又は 関数の名前にだけ適用できる。
?
指定子は,クラスメンバ 又は 関数仮引
数の宣言に使うことはできない。
?
指定子付きで宣言された名前の結合については,
#
で規定する。
ある名前空間有効範囲の中で《記憶域種別指定子》を伴わずに宣言した名前は,それに先行する宣言によって内部
結合をもっている場合,及び
と宣言されている場合を除き,外部結合をもつ。
と宣言され ,明示的に
と宣言されていないオブジェクトは,内部結合をもつ。
一つの実体に対する一連の宣言が導く結合は,一致していなければならない。すなわち,ある有効範囲において,
同じオブジェクト名を宣言している宣言ど うし ,又は 一つの関数の同じ多重定義を宣言している宣言ど うしは,同じ
結合を導かなければならない。しかし ,多重定義される関数の集合の中の個々の関数が異なる結合をもっていても差
し支えない。
例
!
&
''
は,内部結合
!
''
は,やはり内部結合
Q
'!(((!'
R
!
&
''
は,外部結合
!
''
エラー
3
結合の不一致
Q
'!(((!'
R
&
&
''
外部結合
&
&
''
外部結合
&
&
''
外部結合
&
&
''
内部結合
&
''
は,内部結合
&
''
エラー
3
二つの定義
&
''
は,内部結合
&
''
は,やはり内部結合
&
''
は,外部結合
&
''
エラー
3
結合の不一致
&
''
は,外部結合
&
''
エラー
3
結合の不一致
宣言だけがあって定義がないクラスの名前は,
?
宣言の中で使うことができる。そのような宣言は,完全クラ
ス型を要求しない範囲でだけ,使うことができる。
例
F&
F
&
F
&
F &
Q
&
''
エラー
3
F
が不完全なため
&
''
エラー
3
F
が不完全なため
R
%
指定子は,クラスデータメンバ(
*
)に対してだけ適用でき,
又は
として宣言された名前に
は適用できず,参照メンバにも適用できない。
例
5
Q
!
&
''
B>
!
&
''
不適格
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
クラスのデータメンバに対する
%
指定子は,それを含むクラスオブジェクトに適用された
!
指定子の効
果を取り消し,そのデータメンバの変更を可能にする(
)#
参照)
。ただし,そのオブジェクトの残りの部分の定
値性は変わらない。
)
関数指定子
関数指定子は,関数宣言にだけ使うことができる。
関数指定子
3
関数宣言(
#
,
*
及び
参照)は,
指定子付きの場合,インライン関数の宣言とする。
指定子
は,処理系に対し,通常の関数呼出し機構を使わず,関数本体を呼出し位置にインライン置換をするのが望ましいこ
とを指示する。処理系は,必ずしも呼出し時点でのインライン置換を行わなくてもよいが,インライン置換しない場
合であっても,
)
で規定するインライン関数のそれ以外の規則には従わなければならない。
クラス定義の中で定義される関数は,インライン関数とする。
指定子は,ブロック有効範囲をもつ関数宣言
に現れてはならない。
インライン関数は,それを使用する翻訳単位ごとに定義しなければならず,すべてが完全に同じ定義でなければな
らない(
参照)
。
参考
翻訳単位中で,インライン関数を定義する前に,そのインライン関数の呼出しを書いてもよい。
ある翻訳単位中で
として宣言した関数が外部結合をもつ場合,その関数が現れるすべての翻訳単位において
と宣言しなければならない。診断は,不要とする。外部結合をもつインライン関数中の静的な局所変数は,常
に同じオブジェクトを参照する。外部結合をもつインライン関数中の文字列リテラルは,異なる翻訳単位であっても
同じオブジェクトとする。
0
指定子は,クラス宣言中のメンバ指定の中に現れる非静的クラスメンバ関数の宣言にしか使ってはならない
(
参照)
。
?1
指定子は,クラス宣言中のコンストラクタの宣言にしか使ってはならない(
参照)
。
)
"
指定子
1 3
指定子をもつ《宣言》は,
《識別子》を宣言し ,後で基本型(
*
) 又は 複合型
(
*
)を名指すことができるようにする。
1
3
指定子は,関数定義(
)に使ってはならず,
《宣言指定子列》
の中で《型指定子》以外の指定子と組み合わせて使ってはならない。
型定義名
3
識別子
1
3
指定子によって宣言された名前は,
《型定義名》となる。その宣言の有効範囲内で,
《型定義名》は,構文規則
上ではキーワード と同等とし ,
での規定に従って,その識別子に結び付いた型を名指す。したがって,
《型定義名》
は,一つの型の別名になる。
《型定義名》は,クラス宣言(
*
) 又は 列挙体宣言とは異なり,新たな型を作り出し
はしない。
例
@<?8F
!>?<7>FC&
この宣言の後に次の構文が来た場合,すべて正当な宣言となる。
@<?8F
&
>?<7>FC
&
の型は
になり,
の型は
:
へのポインタ
;
になる。
クラスではない有効範囲の中で,
1
3
指定子を使って,その有効範囲内で宣言された別の型の名前を再定義し
てもよく,その結果としてかつて参照していた型を再参照するようになっても差し支えない。
例
Q'!
(((
!'R
&
<&
<&
<
<&
有効範囲の中で,
1
3
指定子を使ってその有効範囲内で宣言された他の型の名前を再定義し ,別の型を参照す
るようにしてはならない。
例
Q
'!
(((
!'
R&
&
''
エラー
3
再定義
注
キーワード
は,関数の結合に影響を与えない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
同様に,有効範囲の中で,クラス 又は 列挙体を宣言するのに,そのクラス 又は 列挙体とは別の型を参照するように
その有効範囲で宣言されている《型定義名》と同じ名前を使ってはならない。
例
&
Q
'!
(((
!'
R&
''
エラー
3
再定義
クラスを名指す《型定義名》は,
《クラス名》
(
*
)となる。
《詳述型指定子》
(
)#
)の中 又は クラス宣言の《ク
ラス先頭語》の中で,
《クラスキー》に引き続いて《型定義名》が使用されている場合,又は コンストラクタ(
)
又は デストラクタ(
)を宣言する《宣言子》の中で《型定義名》が《識別子》として使用されている場合,その
プログラムは不適格とする。
例
F
Q
F &
XF &
R&
F
&
F
%
&
''
B>
!
&
''
エラー
型定義の宣言が無名のクラス( 又は 列挙体)を定義する場合,その宣言によってそのクラス型( 又は 列挙型)に
なることを宣言される最初の《型定義名》は,結合目的(
#
参照)の場合にだけ,そのクラス型( 又は 列挙型)を
表すのに使うことができる。
例
Q
R
!
F&
''
F
は,結合目的のクラス名になる。
《クラス名》
( 又は 《列挙体名》)が必要なところに,この最初の《型定義名》を使っている場合,そのプログラムは
不適格とする。
例
Q
F &
''
エラー
3
F
は,通常のメンバ関数であってコンストラクタで
''
ないから,返却値型が必要である。
R
F&
)
"
指定子
3
指定子は,クラスメンバへのアクセスを指定するために使う(
参照)
。
)#
型指定子
型指定子の構文規則は,次のとおりとする。
型指定子
3
単純型指定子
クラス指定子
列挙体指定子
詳述型指定子
0
修飾子
一般規則として,
《宣言》の《宣言指定子列》全体の中には,高々一つの《型指定子》しか許されない。この規則に対
する例外は,次のとおりとする。
―
及び
は,任意の《型指定子》と組み合わせることができる。しかし,型定義(
)
) 又
は テンプレートの型実引数(
)を使って導入される場合(これらの場合,冗長な
0
修飾子は,無視
される。)を除き,冗長な 《
0
修飾子》は,禁止されている。
―
又は
は,
,
,
又は
のいずれかと組み合わせることができる。
―
又は
は,
と組み合わせることができる。
―
は,
と組み合わせることができる。
コンストラクタ,デストラクタ 及び 変換関数を宣言する場合を除き,
《宣言》内には,
《
0
修飾子》とは異なる少な
くとも一つの《型指定子》を必要とする。
参考
《クラス指定子》 及び 《列挙体指定子》については,それぞれ
*
及び
)
で規定する。その他の《型
指定子》については,
)#
〜
)#
で規定する。
注
《型指定子》のない《宣言指定子列》,又は 《
"#
修飾子》だけを指定している《型指定子》をもつ《宣言指定子列》に対する特別な規
定はない。
言語の
暗黙の
の規則は,
では許されていない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
)#
'
修飾子
0
修飾子には,
及び
がある。
《
0
修飾子》が《宣言指定子列》にある場合,そ
の宣言の《初期化宣言子並び》は,空であってはならない。
参考
*
に,オブジェクト型 及び 関数型に
0
修飾子が与える影響を規定している。
と明示宣言されていない場合,又は 外部結合をもつことを先に宣言していない場合,名前空間有効範囲の
中で宣言された
修飾の付いた型をもつオブジェクトは,内部結合をもつ。
が付かなくて
修飾
の付いた汎整数型 又は 列挙型の変数は,汎整数定数式で初期化されている場合,汎整数定数式の中で使ってもよい
(
#*
参照)
。
参考
#
で規定するように,
修飾付き型をもつオブジェクト 又は 部分オブジェクトの定義では,初期
化子を指定するか,省略時初期化の対象にするかしなければならない。
0
修飾付き型へのポインタ 又は 参照は,
0
修飾付きオブジェクトを実際に指しているか参照しているかする必
要はないが,そうしているとして扱われる。
修飾付きのアクセスパスを使って,オブジェクトを変更してはな
らない。この禁止は,参照されるオブジェクトが定値オブジェクトであるか否か,他のアクセスパスから変更できる
か否かに依らない,
参考
0
修飾子は,型の体系に組み込まれているので,キャスト(
#
)を使わない限り無効にはできない。
(
)
)と宣言したクラスメンバは,変更可能とする。これに当てはまらない定値オブジェクトをその生
存期間(
)中に変更しようとした場合,その結果の挙動は未定義とする。
例
%
*&
''
修飾( 要求ど おり初期化している。)
%
M&
''
不適格
3
を変更しようとした。
%
+&
''
修飾なし 。
!
&
''
へのポインタ
%
0&
''
B>3
修飾付きアクセスパスが,修飾なしの
''
オブジェクトを指している。
!
%
M&
''
不適格
3
へのポインタで
''
変更しようとした。
!
&
%
P!
&
''
!
から
!
への変換キャストが必要。
!
%
M&
''
定義される
3
は,
をポイントしており,
''
これは,定値オブジェクトではない。
!
%
* &
''
初期化される。
!
%
P!
&
''
キャストが必要。
!
%
M&
''
未定義
3
定値オブジェクトの変更である。
別の例を次に示す。
例
5
Q
3
&
&
R&
J
Q
3
5
&
J
&
R&
J
&
(())&
''
適格
3
メンバは変更できる。
(())&
''
不適格
3
修飾のメンバは変更できない。
J!
%
PJ!0
&
''
をキャストして定値でなくする。
CV(
%
OO&
''
適格
3
メンバはキャストできる。
V(
%
OO&
''
未定義
3
定値メンバを変更しようとしている。
修飾付き型と定義されたオブジェクトを,
修飾なし型の左辺値を使って参照しようとした場合,
そのプログラムの挙動は,未定義とする。
参考
の指定は,その属性のオブジェクトの値が処理系で検出不可能な手段で変更されうるので,そ
ういうオブジェクトに対する過度の最適化処理を避けるようにというヒントを,処理系に与える。詳細な
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
意味規則は,
*
に規定してある。一般に,
"##
における
の意味は,
"
での意味と同じになる
ように意図している。
)#
単純型指定子
単純型指定子の構文規則は,次のとおりとする。
単純型指定子
3
33
入れ子名前指定子
型名
33
入れ子名前指定子
テンプレート識別子
P
型名
3
クラス名
列挙体名
型定義名
《単純型指定子》は,既に宣言された利用者定義の型 又は 基本型(
*
)のいずれかを指定する。
表
)
に,
《単純型
指定子》とそれが指定する型の正しい組合せとをまとめて示す。
表
)
《単純型指定子》 及び それが指定する型
指定子
型
:
;
: !3
;
:!3
;
:%
;
: !3
;
: !3
;
:
;
:
;
:
;
: !3
!
;
: !3
!
;
: !3
;
: !3
;
:
;
:
;
:
;
:
;
:!
;
:!
;
:!
;
:!
;
:<
;
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
表
)
《単純型指定子》 及び それが指定する型( 続き)
指定子
型
:5;
:3 %;
:
3 %;
:0
3;
複数の《単純型指定子》が許可されている場合,それらと他の《宣言指定子》とを任意の順序で自由に混ぜて指定
してもよい。ビットフィールド 及び
型のオブジェクトを,符号付きとするか符号なしとするかは,処理系定義
とする。
!3
指定子は,
型オブジェクト 及び ビットフィールド を強制的に符号付きとする。その他の汎整数
型に対しては,効果をもたない。
)#
詳述型指定子
詳述型指定子
3
クラスキー
33
入れ子名前指定子
識別子
クラスキー
33
入れ子名前指定子
テンプレート識別子
33
入れ子名前指定子
識別子
33
入れ子名前指定子
識別子
33
入れ子名前指定子
テンプレート識別子
詳述型指定子だけからなる《宣言》は,明示的特殊化(
)
),明示的具現化(
)
) 及び 次の形式の場合
を除き,不適格とする。
クラスキー
識別子
&
クラスキー
33
識別子
&
クラスキー
33
テンプレート識別子
&
クラスキー
33
入れ子名前指定子
識別子
&
クラスキー
33
入れ子名前指定子
テンプレート識別子
&
《詳述型指定子》中の《識別子》は,名前検索によってその表すものを見つけ出す(これを,名前検索が解決する
という。)。名前検索の処理は,
に規定する。
《識別子》が《クラス名》 又は 《列挙体名》と解決された場合,
《単純型指定子》がその型名を導入するのと同じように,
《詳述型指定子》は,その《識別子》をその宣言に導入する。
《識別子》が《型定義名》 又は テンプレート《型仮引数》と解決された場合,その《詳述型指定子》は不適格とする。
参考
したがって,
《型仮引数》
というテンプレートをもつクラステンプレートの中では,次の宣言は,不適
格となる。
&
名前検索からその名前に対する宣言が見つからない場合,その《詳述型指定子》は,不適格とする。ただし,その《詳
述型指定子》が
:
《クラスキー》 《識別子》
;
という形式である場合を除く。この場合には,
によってその《識
別子》が宣言される。
《詳述型指定子》の中に現れる《クラスキー》 又は キーワード
は,その《詳述型指定子》中の名前が参照
している宣言での種別と一致していなければならない。この規則は,
《クラス名》 又は
付きのクラスを宣言
する《詳述型指定子》に対しても適用される。こうした《詳述型指定子》は,そのクラスの定義を参照していると解
釈されるからである。すなわち,どんな《詳述型指定子》においても,列挙型(
)
)を参照するためにはキーワー
ド
を使わなければならず,共用体(
*
)を参照するためにはキーワード
を使わなければならず,クラス
キー
又は
を使って宣言されたクラス(
*
)を参照するにはクラスキー
又は
をそれぞ
れ使わなければならない。
)
列挙体宣言
列挙体は,名前付き定数をもつ別個の型(
*
)とする。その名前は,その有効範囲内では《列
挙体名》とする。
列挙体名
3
識別子
列挙体指定子
3
識別子
列挙子並び
列挙子並び
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
列挙子定義
列挙子並び
列挙子定義
列挙子定義
3
列挙子
列挙子
%
定数式
列挙子
3
識別子
《列挙子並び》中の《識別子》は,定数として宣言され,定数が必要な場所のどこに使ってもよい。
%
をもつ《列挙子
定義》は,対応する《列挙子》に《定数式》で示される値を与える。
《定数式》は,汎整数型 又は 列挙型でなければ
ならない。最初の《列挙子》に《初期化子》がない場合,対応する定数の値は,ゼロとする。
《列挙子定義》に《初期
化子》がない場合,対応する《列挙子》には,その直前の列挙子の値に
を加えた値が与えられる。
例
Q
%
.
R&
Q
%
)+
R&
この例では,
,
及び
をゼロと定義し ,
及び
を
と定義し ,そして
を
*
と定義している。
列挙子に対する宣言時点とは,
《列挙子定義》の直後とする。
例
%
L+&
Q
Q
%
R
&R
ここで,列挙子
は,定数値,すなわち
で初期化される。
それぞれの列挙体は,他のすべての型と異なる型を定義する。
《列挙体指定子》の閉じ波括弧の後では,各列挙子
は,その列挙体の型をもつことになる。閉じ波括弧の前では,各列挙子の型は,その初期化に用いられる値の型とす
る。列挙子に初期化子が指定されている場合,初期化に用いられる値の型は,その式と同じ型とする。列挙子に対し
初期化子が指定されていない場合,それが最初に列挙子であれば ,その型は,指定なしの汎整数型とする。そうでな
ければ ,その型は,先行する列挙子の初期化に用いられた値の型と同じとする。ただし ,
加えた値がその型で表現
できなくなったときは,
加えた値を保つのに足りる指定なし汎整数型とする。
列挙体の基礎とする型は,列挙体中に定義されたすべての列挙子値を表現できる汎整数型とする。基礎とする型と
してどの汎整数型を使うかは,処理系依存とする。ただし,列挙子の値が
又は
の範囲に入ってい
る限り,
より大きいものであってはならない。
《列挙子並び》が空の場合,基礎とする型は,その列挙体が値
の
列挙子を一つもつ場合と同じとする。列挙型,列挙型のオブジェクト 又は 列挙子に対して適用した
$
の値
は,それが基礎とする型に適用した
$
の値となる。
ある列挙体は,その最小の列挙子を
とし,最大の列挙子を
としたとき,その値の集合として,基礎とす
る型の値のうちの,
から
までの値をもつ。ここで,
及び
は,それぞれ
及び
を格納で
きる最小のビットフィールド の最小値 及び 最大値とする
。どの列挙子においても定義していない値をもつ列挙
体を定義することができる。
二つの列挙型は,その基礎とする型が同じ場合,配置互換とする。
列挙子の値 又は 列挙体の型のオブジェクトは,汎整数型昇格によって整数に変換される(
#
参照)
。
例
Q
%+.
R&
%
&
!
%
0&
!
%%
''(((
この例では,
を種々の色を記述する型とし ,
をその型のオブジェクトとして宣言し,
をそ
のオブジェクトへのポインタとして宣言する。型
のオブジェクトに入りうる値は,
,
,
及び
となる。それらの値は,汎整数の値
,
,
及び
に変換できる。列挙型は別個の型
なので,型
のオブジェクトには,型
の値しか代入することができない。
%
L
&
''
エラー
3
型が一致しない。
''
から
への変換はない。
%
&
''
B>3
は,汎整数値
L
に変換される。
''
汎整数型昇格を適用する。
注
の補数方式の機械においては,
は,
という形の数であって,
*+
を下回らない最小の
数とする。
は,
が負でなければゼロ,そうでなければ
とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
算術型 又は 列挙型の式は,明示的に列挙型に変換することができる。列挙型の列挙値の範囲にある場合,値は,変
換によっても変化しない。そうでない場合,結果の列挙値は,規定しない。
《列挙体名》 及び 列挙体指定子によって宣言された各列挙子は,その列挙体指定子を直接に含む有効範囲の中で宣
言される。これらの名前は,すべての名前に対する有効範囲規則(
及び
参照)に従う。クラス有効範囲内で
宣言された列挙子は,そのクラスのメンバアクセス演算子(
33
,
(
及び
V
)を使って参照することができる(
##
参照)
。
例
5
Q
3
Q
%ZZ
%ZZ
R&
Q
%%
2
.
3
%%
2
L
3
+&
R
R&
5!
Q
&
''
エラー
3
は有効範囲にない。
&
%
V &
''
エラー
3
は有効範囲にない。
%
V533 &
''
B>
%
VV &
''
B>
''(((
R
)
名前空間
名前空間は,宣言領域の一つとする。それには,名前を付けても付けなくてもよい。名前空間の名前
は,その名前空間内に宣言されたもの,すなわち,その名前空間のメンバをアクセスするために使ってよい。他の宣
言する領域とは異なり,名前空間は,一つ以上の翻訳単位の複数の部分で分割して定義してもよい。
翻訳単位の最外側の宣言領域は,名前空間の一つとする(
#
参照)
。
)
名前空間定義
名前空間定義の文法は,次のとおりとする。
名前空間名
3
原名前空間名
名前空間別名
原名前空間名
3
識別子
名前空間定義
3
名前付き名前空間定義
名前なし名前空間定義
名前付き名前空間定義
3
原名前空間定義
拡張名前空間定義
原名前空間定義
3
識別子
名前空間本体
拡張名前空間定義
3
原名前空間名
名前空間本体
名前なし名前空間定義
3
名前空間本体
名前空間本体
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
宣言列
《原名前空間定義》の《識別子》は,その《原名前空間定義》が存在する宣言領域内にあらかじめ定義してあって
はならない。
《原名前空間定義》の《識別子》は,名前空間の名前となる。その後で,その名前は,その宣言領域内で
《原名前空間名》として扱われる。
《拡張名前空間定義》の《原名前空間名》は,同じ宣言領域内にある《原名前空間定義》の中で前もって定義され
ていなければならない。
すべての《名前空間定義》は,大域的有効範囲 又は 名前空間有効範囲のいずれかの中にある(
#
参照)
。
《名前空間定義》は,その《名前空間本体》内に《宣言》を記述でき,それ自身《宣言》であるので,入れ子にす
ることができる。
例
B
Q
&
<
Q
Q
))&
R
''
B33
&
Q
))&
R
''
<33
R
R
)
名前なし名前空間
《名前なし名前空間定義》は,次のもので置き換えたかのように動作する。
'!
空の本体
!'
&
名前空間本体
ただし,翻訳単位内の
の出現すべてを,同じ一つの識別子で置換しておく。その識別子には,プログラム
全体の他のすべての識別子と異なるものを採用する。
例
&
''
33
))&
''
33
6
&
''
63333
&
''
63333
))&
''
63333
6&
))&
''
エラー
3
33
なのか
''
63333
なのか不明
633))&
''
63333
))&
''
63333
名前空間有効範囲内でオブジェクトを宣言するとき,キーワード
の使用は,推奨しない(
附属書
5
参照)
。
名前なし名前空間を代りに使うことを推奨する。
)
名前空間メンバの定義
名前空間のメンバは,その名前空間の中で定義することができる。
例
5
Q
Q
'!
(((
!'
R
R
名前付き名前空間のメンバは,定義したい名前を明示的に修飾(
)することによって,その名前空間の外側
で定義することもできる。ただし,定義したいメンバ実体を前もってその名前空間内で宣言しておき,その宣言の存
在する名前空間を囲む名前空間のいずれかの中の,その宣言よりも後に,その定義を書かなければならない。
例
D
Q
H
Q
&
注
名前なし名前空間内の実体は,外部結合をもたせても差し支えない。しかし,その翻訳単位に限定される一意的な名前を使って修飾さ
れるので,その他の翻訳単位から見えることはない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
R
H33
Q
'!(((!'
R
''
B>
H33
Q
'!(((!'
R
''
エラー
3
は,まだ
H
のメンバでない。
H
Q
&
R
R
E
Q
D33H33
Q
'!(((!'
R
''
エラー
3
E
は,
D
を取り囲んでいない。
R
名前空間で最初に宣言された名前は,その名前空間のメンバとする。局所的でないクラスの中でクラス 又は 関数
が,随伴宣言によって最初に宣言された
場合,その随伴クラス 又は 随伴関数は,その局所的でないクラスを最
も内側で取り囲む名前空間のメンバとする。この随伴対象の名前は,単純名前検索によっては見つけられず,その名
前空間有効範囲の中に一致する宣言があった( 随伴性を与えるクラス宣言の前でも後でもよい。)ときに見つかる。随
伴関数が呼び出されるのは,その名前が,関数実引数(
)の型に関連する名前空間 及び クラスに由来する関数
を考慮する名前検索によって見つかった場合もありうる。
として宣言されたクラス 又は 関数の先行した宣言
を探すとき,その随伴クラス 又は 随伴関数が修飾付き名前でもテンプレート識別子でもない場合,それを取り囲む
最も内側の名前空間有効範囲の外側にある有効範囲は,検索の対象にしない。
例
''
及び
は,まだ定義されていないものとする。
&
+ &
6
Q
5
Q
5 &
''
6335
は,随伴となる。
J
Q
&
''
633
は,随伴となる。
+ &
''
33+
は,随伴となる。
&
''
633
は,随伴となる。
R&
''
33
は,考慮されない。
R&
''
633
,
633
及び
633
は,ここでは見えない。
5
&
Q
&
R
''
633
を定義している。
5
Q
'!
(((
!'
R
''
633
を定義している。
Q
'!
(((
!'
R
''
633
を定義している。
''
633
,
633
及び
633
は,ここからは見えて,随伴と判る。
R
633&
Q
633 &
633533 &
''
エラー
3
は,
6335
のメンバではない。
633533J33 &
''
エラー
3
は,
633533J
のメンバではない。
R
)
名前空間別名
名前空間別名定義は,次に示す文法に従って,名前空間に対する代替の名前を宣言する。
名前空間別名
3
識別子
名前空間別名定義
3
識別子
%
修飾付き名前空間指定子
&
修飾付き名前空間指定子
3
33
入れ子名前指定子
名前空間名
《名前空間別名定義》内の《識別子》は,
《修飾付き名前空間指定子》内の名前空間名と同義語としての《名前空間
別名》になる。
注
これによって,そのクラス 又は 関数の名前は,修飾なしになる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
参考
《名前空間別名定義》内の《名前空間名》を検索するときは,名前空間名だけを検索対象にする(
(
参照)
。
宣言領域の中では,
《名前空間別名定義》を使って《名前空間別名》を再定義してよい。ただし ,その《名前空間別
名》がすでに参照している当の名前空間を再度参照する形の再定義に限る。
例
次の宣言は,適格とする。
7PP
P
P
Q
'!
(((
!'
R
7IH?A
%
7PP
P
P
&
7IH?A
%
7PP
P
P
&
''
B>3
重複してもよい。
7IH?A
%
7IH?A&
《名前空間名》 及び 《名前空間別名》は,その同じ宣言領域内で,その他の実体の名前として宣言してはならな
い。
《名前空間名》は,大域的有効範囲で定義された場合,そのプログラムの大域的有効範囲内で,その他の実体の
名前として宣言してはならない。異なる翻訳単位の宣言がこの規則に違反している場合,診断は不要とする。
)
宣言
!
宣言は,それが現れた宣言領域に名前を一つ導入する。その名前は,別の場所で宣言され
た実体の名前の同義語とする。
!
宣言
3
33
入れ子名前指定子
修飾なし識別子
&
33
修飾なし識別子
&
《
!
宣言》で指定したメンバ名は,
《
!
宣言》が現れた宣言領域の中で宣言済みとして扱う。
参考
指定した名前だけが,そういう宣言の扱いを受ける。列挙体名を《
!
宣言》で指定した場合,その
列挙子まで《
!
宣言》が現れる宣言領域の中で宣言したことにはならない。
すべての《
!
宣言》は,
《宣言》でもあり,
《メンバ宣言》でもあるので,クラス定義の中で使うことができる。
例
"
Q
&
&
8
Q
R&
Q
&
R&
R&
#
3
"
Q
"33&
Q
ZZ &
R
''
"33
の呼出しとなる。
Q
ZZ &
R
''
#33
の再帰的呼出しとなる。
R&
クラスの《メンバ宣言》として使う《
!
宣言》は,次のいずれかを参照していなければならない。
―
そのクラスの基底クラスのメンバ
―
そのクラスの基底クラスのメンバになっている無名共用体のメンバ
―
そのクラスの基底クラスのメンバになっている列挙型に対する列挙子
例
7
Q
&
R&
#+
3
"
Q
"33&
''
B>3
"
は,
#+
の基底クラス
"33&
''
B>3
は,基底クラス
"
の列挙子
"33&
''
B>3
は,基底クラス
"
の共用体メンバ
733&
''
エラー
3
7
は,
#+
の基底クラスでない。
R&
参考
コンストラクタ 及び デストラクタは,名前をもっていないので,
《
!
宣言》で基底クラスのコンス
トラクタ 又は デストラクタを参照することはできない。変換関数に対し特殊化したメンバテンプレート
は,名前検索で見つからないので,
《
!
宣言》で変換関数を指定したとき,検索対象にならない(
#
参照)
。
基底クラスから派生クラスに持ち込まれた代入演算子が,派生クラス(
)のコピー代入演算子の呼出し情報をもっ
ている場合,
《
!
宣言》は,派生クラスのコピー代入演算子の暗黙宣言をそれ自身としては無効にすることはない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*#
基底クラス由来のコピー代入演算子は,次に規定するように,暗黙宣言される派生クラスのコピー代入演算子によっ
て隠ぺいされるか,上書きされることがある。
《
!
宣言》に,テンプレート識別子を使ってはならない。
例
6
Q
3
&
5
Q
R&
R&
"
3
6
Q
3
633&
''
不適格
633&
''
不適格
R&
クラスメンバに対する《
!
宣言》は,
《メンバ宣言》となっていなければならない。
例
5
Q
&
&
R&
Q
533&
''
エラー
3
533
はクラスメンバであるが
''
この宣言はメンバ宣言でない。
533&
''
エラー
3
533
はクラスメンバであるが
''
この宣言はメンバ宣言でない。
R
《
!
宣言》を使って宣言するメンバは,他のメンバ名と同じように,明示的修飾によって参照してもよい(
参照)
。
《
!
宣言》において,接頭語
33
は,大域的名前空間の参照とする。
例
&
6
Q
&
R
5
Q
33&
''
大域的な
633&
''
6
の
R
Q
533 &
''
33
を呼び出す。
533 &
''
633
を呼び出す。
R
《
!
宣言》は,一つの《宣言》なので,多重の宣言が許されている場合には(その場合に限り),繰り返して宣
言してもよい。
例
6
Q
&
R
6L
Q
633&
633&
''
B>3
二重の宣言
R
Q
633&
633&
''
エラー
3
二重の宣言
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*(
"
Q
3
&
R
5
3
"
Q
"33&
"33&
''
エラー
3
二重のメンバ宣言
R&
《
!
宣言》によって宣言される実体は,それを使う文脈において,その《
!
宣言》時点での定義状態に応じ
たものだけとする。
《
!
宣言》の後でその名前空間に定義が追加されても,その名前が使われるときに,その定義
が考慮されることはない。
例
6
Q
&
R
633&
''
は,
633
の同義語となる。
''
すなわち,
633
6
Q
&
R
Q
ZZ &
''
が存在していても,
を呼び出す。
R
''
Q
633&
''
は,
633
,すなわち,
633
及び
633
''
の同義語となる。
ZZ &
''
を呼び出す。
R
参考
部分特殊化したクラステンプレートは,一次クラステンプレートを検索し ,さらにそのテンプレートの
すべての部分特殊化を検索することによって見つかる。
《
!
宣言》がクラステンプレートを指す場合,
その一次テンプレートが見えているので,その
!
宣言の後で行った部分特殊化も実効的に見えること
になる(
#
参照)
。
《
!
宣言》は,宣言の一種なので,同じ宣言領域(
)での同じ名前の宣言に対する制約は,
《
!
宣言》に
も適用される。
例
6
Q
&
R
"
Q
&
Q
R&
Q
R&
&
&
&
''
B>3
を隠ぺいする。
R
Q
&
"33&
''
エラー
3
は,二重の宣言。
&
"33&
''
B>3
それぞれの
は,別個の関数。
*(/ &
''
これは,
"33
を呼び出す。
"33&
ZZ &
''
"33
を呼び出す。
L&
''
L
は,クラス型
"33
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*)
"33&
633&
''
B>3
"33
を隠ぺいする。
%
OO&
''
633
への代入。
L&
''
L
の型は,クラス型
"33
となる。
R
名前空間有効範囲 又は ブロック有効範囲にある関数宣言で宣言された関数が,
《
!
宣言》で導入した関数と同じ
名前 及び 同じ仮引数型をもち,それらの宣言が同じ関数を宣言していない場合,そのプログラムは,不適格とする。
参考
二つの《
!
宣言》が,同じ名前 及び 同じ仮引数型の関数を導入するのはかまわない。修飾なしの関
数名の呼出しに対し ,関数の多重宣言解決が,それらの《
!
宣言》で導入された複数の関数を選択し
た場合,その関数呼出しは,不適格とする。
例
"
Q
&
&
R
7
Q
&
&
&
R
Q
"33&
''
"33
及び
"33
733&
''
733
,
733
及び
733
ZZ &
''
733
を呼び出す。
L &
''
エラー
3
あいまい
3
"33
か
733
''
かが不明。
&
''
エラー
3
は,
733
及び
"33
''
と重複する。
R
《
!
宣言》を使って派生クラスの有効範囲にその基底クラスから名前を導入したとき,派生クラスのメンバ関
数は,同じ名前 及び 同じ仮引数型をもつ基底クラスからのメンバ関数を,上書き 及び/又は 隠ぺいする( 重複では
ない。)
。
例
"
Q
&
&
&
&
R&
#
3
"
Q
"33&
&
''
B>3
#33
が
"33
を上書きする。
"33&
&
''
B>
"33&
&
''
B>3
#33
が
"33
を隠ぺいする。
R&
#!
Q
V
L &
''
#33
を呼び出す。
V
ZZ &
''
"33
を呼び出す。
V
L &
''
"33
を呼び出す。
V
ZZ &
''
#33
を呼び出す。
R
参考
二つの《
!
宣言》が,同じ名前 及び 同じ仮引数型をもつ関数を導入してもかまわない。修飾なしの
関数名の呼出しに対して,関数の多重宣言解決が,そういう《
!
宣言》で導入された複数の関数を選
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
択した場合,その関数呼出しは,不適格とする。
多重定義解決のためには,
《
!
宣言》によって派生クラスに導入された関数は,その派生クラスのメンバである
かのように扱われる。特に,暗黙的な仮引数
は,基底クラスへのポ インタではなく,派生クラスへのポインタ
として扱われる。このことは,その関数の型に影響を与えない。その他のすべての観点では,その関数は,基底クラ
スのメンバのままとする。
《
!
宣言》で指定した名前のすべてのインスタンスは,アクセス可能でなければならない。特に,派生クラス
から《
!
宣言》を使って基底クラスのメンバをアクセスする場合,そのメンバ名は,アクセス可能でなければな
らない。その名前が多重定義されているメンバ関数の場合,その名前のすべての関数がアクセス可能でなければなら
ない。
《
!
宣言》で指定する基底クラスのメンバは,
《
!
宣言》が指定されたクラスの直接の基底クラスのうち
少なくとも一つのクラスの有効範囲において可視でなければならない。
参考
《
!
宣言》は,基底クラスのメンバを指すので( 基底クラスの部分オブジェクトの,メンバ部分オ
ブジェクト 又は メンバ関数ではないので ),
《
!
宣言》は,継承されたメンバのあいまい性を解決する
のに使うことはできない。
例
6
Q
&
R&
"
3
6
Q
R&
7
3
6
Q
633&
&
R&
#
3
"
7
Q
733&
&
R&
#!
Q
V &
''
あいまい
3
"335
なのか
7335
なのかが不明。
R
《
!
宣言》で導入される別名は,アクセスに関して《メンバ宣言》による名前と同等とする。
例
6
Q
3
&
3
&
3
&
R&
"
3
6
Q
633&
''
エラー
3
633
にアクセスできない。
3
633&
''
"33
は,
633
の公開の同義語となる。
R&
参考
《アクセス宣言》
(
)を使うことは,推奨しない。メンバの《
!
宣言》を使うほうがよい。
)
指令
!
指令
3
33
入れ子名前指定子
名前空間名
&
!
指令は,クラス有効範囲に現れてはならないが,名前空間有効範囲 又は ブロック有効範囲には現れてもよい。
参考
《
!
指令》の中の《名前空間名》を検索するとき,名前空間名だけが対象になる(
(
参照)
。
《
!
指令》によって,そこに指名した名前空間内の名前を,その《
!
指令》を書いた有効範囲の中で,その
《
!
指令》の後で,使うことができる。修飾なし名前の検索(
)の最中は,その名前は,
《
!
指令》 及び
指名した名前空間の両方を含んでいる最も内側で取り囲む名前空間の中で宣言されたように見える。
参考
ここで,
:
含んでいる
;
とは,
:
直接的 又は 間接的に含んでいる
;
という意味とする。
《
!
指令》は,それが指定された宣言領域に新たなメンバを付加することはない。
例
6
Q
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
**
"
Q
7
Q
&
R
633"337&
L
Q
%
/&
''
B>3
733
は,
"
の名前空間で可視であり,
633
を
''
隠ぺいする。
R
R
#
Q
"&
7&
+
Q
%
/&
''
あいまい
3
"33733
なのか
633
なのかが不明。
R
R
*
Q
%
/&
''
633
を使う。
R
R
M
Q
%
/&
''
不適格
3
どの
も見えない。
R
《
!
指令》は,推移的とする。すなわち,名前空間有効範囲 又は ブロック有効範囲の中に《
!
指令》があ
り,そこに指名した名前空間自体の中にも《
!
指令》がある場合,その名前空間の《
!
指令》が最初の有効範
囲にもあるような効果をもたらす。
例
@
Q
&
R
A
Q
&
@&
R
Q
A&
%
,&
''
エラー
3
@33
と
A33
の両方が可視である。
R
もう一つ例を示す。
6
Q
&
R
"
Q
&
&
7
Q
#
Q
6&
&
&
%
&
''
"33
が
633
を隠ぺいする。
R
#&
%
NO&
''
まだ問題ではない。
%
&
''
あいまい
3
733
なのか
#33
なのかが不明。
%
&
''
"33
が
633
を隠ぺいする。
%
&
''
#33
が
"33
を隠ぺいする。
R
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ある名前空間に対する《
!
指令》の後で,その名前空間が《拡張名前空間定義》によって拡張された場合,拡
張された名前空間で加わるメンバ 及び 《拡張名前空間定義》内の《
!
指令》で指名した名前空間のメンバが,そ
の《拡張名前空間定義》の後で使用可能となる。
名前検索の際,ある名前の宣言が二つの異なる名前空間で見つかった場合,かつ その二つの宣言が同じ実体を宣言
していない場合( 関数を宣言している場合を除く。),その名前の使用は,不適格とする。
参考
特に,オブジェクト,関数 又は 列挙子の名前は,異なる名前空間で宣言されているクラス 及び 列挙子
の名前を隠ぺいしない。
例
6
Q
5
Q
R&
Y7Y
&
Y7))Y
&
R
"
Q
5 &
Y7Y
&
Y7))Y
&
R
6&
"&
Q
5L &
''
エラー
3
5
は,二つの名前空間で見つかる。
&
''
B>3
は,同じ実体を参照する。
&
''
エラー
3
は,二つの名前空間で見つかる。
R
多重定義解決のとき,推移的検索で見つかるすべての関数について,実引数が一致するかど うかが検討される。推
移的検索で宣言を見つけた順序は,何の意味ももたない。
参考
特に,名前空間を考慮した順序,及び 《
!
指令》から生じた名前空間間の推移的関係は,検索で見
つかる宣言のいずれにも優位性を与えることはない。
最適一致によって同じ呼出し情報をもつ関数が二つ見つかったときは,たとえ一方が他方の名前空間の中の《
!
指
令》を通して到達可能な名前空間にあったとしても,あいまいとする。
例
#
Q
L&
&
R
#&
L&
''
B>3
#33L
との競合はない。
8
Q
&
&
R
#
Q
''
名前空間拡張
+&
8&
&
R
Q
L))&
''
エラー
3
33L
か
#33L
かがあいまい。
33L))&
''
B>
#33L))&
''
B>
+))&
''
B>3
#33+
))&
''
B>3
833
注
クラス階層の中を名前検索するときには,あるメンバが他のメンバをあるパスに従うと隠ぺいするかしないかを考慮することによって,
あいまいさが解決することもある(
参照)
。後続の《
指令》の結果として見つかる名前の集合に関しては,このようなあいま
い性の解消は,起こらない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
L &
''
エラー
3
#33
か
833
かがあいまい。
ZZ &
''
B>3
#33
R
)
宣言
!
宣言の形式は,次のとおりとする。
!
定義
3
文字列リテラル
&
《
!
宣言》の意味は,処理系定義とする。
参考
典型的には,処理系を介してアセンブラに情報を渡すのに使う。
)#
結合指定
すべての関数型,関数名 及び 変数名は,言語結合をもつ。
参考
言語結合をもつ実体に対応する特性の中には,処理系固有のものがあり,それらは,ここでは規定しな
い。例えば ,特定の言語結合が,外部結合をもつオブジェクト 又は 関数の名前を表現する特定の形式と
関連付けられていたり,特定の呼出し規約と関連付けられていたりすることがある。
すべての関数型,関数名 及び 変数名の省略時の言語結合は,
"##
言語結合とする。言語結合が異なる二つの関数型
は,それを除けば同一であっても,別の型とする。
"##
のコード 片 及び
"##
でないコード 片を,結合指定を使って結合(
#
)することができる。
結合指定
3
文字列リテラル
宣言列
文字列リテラル
宣言
《文字列リテラル》が,必要な言語結合を指定する。
《文字列リテラル》の意味は,処理系定義とする。その文字列が
処理系に不明な《結合指定》は,不適格とする。
《結合指定》の中の《文字列リテラル》がプログラム言語を指す場
合,そのプログラム言語のつづりは,処理系定義とする。
参考
つづりは,その言語を定義している文書からとることが推奨され る。例えば ,
6
(
6#6
ではなく ),
9
及び
9BEE6A
(その年次で区別する。)などである。
"##
又は
"
以外の言語結合の意味規則は,
処理系定義とする。
すべての処理系は,
"
プログラム言語で書かれた関数への結合を表す
Y7Y
及び
"##
関数への結合を表す
Y7))Y
を,使えるようにしておかなければならない。
例
&
''
省略時は,
7))
結合となる。
Y7Y
Q
&
''
7
結合となる。
R
《結合指定》は,入れ子になる。
《結合指定》が入れ子の場合,言語結合は,最も内側のもので決まる。
《結合指定》
は,有効範囲を構成しない。
《結合指定》は,名前空間有効範囲(
)にしか使ってはならない。
《結合指定》にお
いて,指定された言語結合は,
《宣言》によって導入されるすべての関数宣言子の関数型,関数名 及び 変数名に適用
される。
例
Y7Y
L!
&
''
名前
L
及び その関数型が
7
言語結合をもつ。
''
は,
7
関数へのポインタになる。
Y7Y
9GA7 &
9GA7
+&
''
名前
+
は,
7))
言語結合となり,
''
その関数型が
7
言語結合となる。
Y7Y
9GA7
*&
''
名前
*
及び その関数型は,
7
言語結合となる。
!+
9GA7! &
''
変数
+
の名前は,
7))
言語結合をもち
''
+
の型は,
7
関数へのポインタ型の仮引数をもつ。
''
7))
関数へのポインタとなる。
"
言語結合は,クラスメンバの名前 及び クラスメンバ関数のメンバ関数型に対しては無視される。
例
Y7Y
9GA7P &
7
Q
L9GA7P! &
''
関数名
L
及び メンバ関数の型は,
7))
言語結合
''
となるが,仮引数は,
9GA7P
へのポインタ型となる。
9GA7P
+&
''
関数名
+
及び メンバ関数の型は,
7))
言語結合だが,
9GA7P!
&
''
データメンバ
の名前は,
7))
言語結合であり,
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
''
データメンバの型は,
9GA7P
へのポインタとなる。
R&
Y7Y
Q
5
Q
&
''
関数名
及び メンバ関数の型は,
7))
言語結合。
+!
&
''
関数名
+
は,
7))
言語結合だが,
''
仮引数は,
9GA7P
へのポインタ型となる。
R&
R
同じ関数 又は 同じオブジェクトの二つの宣言が異なる《結合指定》をもつ場合( すなわち,二つの宣言内の《結
合指定》が異なる《文字列リテラル》を指定している場合),それらが同じ翻訳単位にあるときにはプログラムは不
適格となり,別の翻訳単位にあるときには単一定義規則(
)が適用される。
"##
言語結合をもつ関数の場合を除
き,その関数に対する最初の結合指定に先行して結合指定のない関数宣言を行ってはならない。明示的に結合指定し
た後であれば,結合指定なしで関数を宣言してもよい。先行する宣言において明示的に指定した結合は,そのような
関数宣言によって影響されない。
それぞれの名前に対して,その名前の関数の中では,高々一つの関数が
"
言語結合をもつことができる。同じ関数
名( 修飾している名前空間を無視したときに同じ名前)に対する二つの宣言は,ともに
"
言語結合をもち,別々の名
前空間有効範囲にある場合,同じ関数を参照する。同じ名前( 修飾している名前空間を無視したときに同じ名前)の
オブジェクトに対する二つの宣言は,ともに
"
言語結合をもち,別々の名前空間有効範囲にある場合,同じオブジェ
クトを参照する。
参考
単一定義規則(
)によれば,
"
言語結合をもつ関数 又は オブジェクトの定義は,プログラムに一つ
しか置けない。すなわち,このような関数 又は オブジェクトを,複数の名前空間有効範囲において定義
してはならない。
例
6
Q
Y7Y
&
Y7Y
Q
L&
R
Y7Y
&
R
"
Q
Y7Y
&
''
633
及び
"33
は,
''
同一関数を参照する。
Y7Y
Q
L&
R
''
不適格
3
7
言語結合の
''
関数
が二重定義となる。
R
633
Q
ON&
R
''
7
言語結合の関数
の定義である。
Y7Y
Q
O,&
R
''
7
言語結合の関数
の定義である。
''
633
も
33
も,同一の関数を参照
''
することになる。
内部結合をもつ関数を除き,
《結合指定》の中で最初に宣言した関数は,外部結合をもつ関数として扱う。
例
Y7Y
&
&
''
エラー
この例のプログラムは,不適格となる(
)
参照)
。
波括弧で囲まれた《宣言列》をもつ《結合指定》の形式は,それに含まれる宣言が定義になるのか否かに影響を与え
ない(
参照)
。一つだけの宣言を直接含む《結合指定》は,それに含まれる宣言が定義であるか否かを決定する際
に,
指定子(
)
参照)として扱われる。
例
Y7Y
&
''
宣言となる。
Y7Y
Q
&
''
定義となる。
R
単一の宣言の場合の《結合指定》には,記憶域種別を書いてはならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
Y7Y
&
''
エラー
参考
言語結合は関数型の一部分なので,
( 例えば )
"
関数へのポインタを参照はずししたとき,それが参照す
る関数は,
"
関数と考える。
"##
から他の言語で定義されたオブジェクトへの結合,及び 他の言語から
"##
オブジェクトへの結合は,処理
系依存の定義とし,かつ 言語依存とする。二つの言語処理系におけるオブジェクトの配置の仕方が十分に類似してい
る場合にだけ,そのような結合が可能となる。
宣言子
宣言子は,宣言の中で一つのオブジェクト,関数 又は 型を宣言する。ある宣言の中に現れる《初期化
宣言子並び》には,コンマで区切った《宣言子》の列を書く。それぞれの《宣言子》には,
《初期化子》を書き加えて
もよい。
初期化宣言子並び
3
初期化宣言子
初期化宣言子並び
初期化宣言子
初期化宣言子
3
宣言子
初期化子
《宣言》は,指定子[《宣言指定子列》
(
)
参照)
] 及び 宣言子(《初期化宣言子並び》)から構成される。指定子
は,宣言するオブジェクト,関数 又は 型定義に対して,型,記憶域種別 又は その他の特性を指定する。宣言子は,
そのオブジェクト,関数 又は 型定義に対して,名前を指定する。宣言子は,
!
(へのポインタ)及び
(を返す関
数)などの演算子を含めることで指定子の型を変更することができる。初期値も,
《宣言子》の中で指定することがで
きる。初期化子は,
#
及び
(
で規定する。
宣言の中の個々の《初期化宣言子》は,宣言の中にそれだけがあるかのように個々に解析される。
《宣言子》の構文規則は,次のとおりとする。
宣言子
3
直接宣言子
ポインタ演算子
宣言子
直接宣言子
3
宣言子識別子
直接宣言子
仮引数宣言節
0
修飾子列
例外指定
直接宣言子
S
定数式
T
宣言子
ポインタ演算子
3
!
0
修飾子列
0
33
入れ子名前指定子
!
0
修飾子列
注
複数の宣言子を含む宣言は,通常,その個々の宣言子を一つずつもつ宣言を並べた形式と同等になる。
/
000
1
この宣言は,通常,次の形式と同等になる。
1
1
000
1
ここで
は,
《宣言指定子列》とし ,それぞれの
は,
《初期化宣言子》とする。ただし ,
《宣言子》の一つによって導入された名前が,
《宣言指定子》で使われている型名を隠ぺいしてしまう場合は除く。その場合,その同じ《宣言指定子》が引き続く宣言の中で使われる
とき,それらは同じ意味でなくなる。
例
$
2
000
1
2
2/
1
$
2
のインスタンス
3
個を宣言している。
この例は,次の例とは異なる。
$
2
000
1
2
21
2
1
エラー。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
0
修飾子列
3
0
修飾子
0
修飾子列
0
修飾子
3
宣言子識別子
3
識別子式
33
入れ子名前指定子
型名
《クラス名》は,その名前をもつクラスの宣言の中で,その名前を有効範囲解決演算子
33
を使って修飾したとき
に,特別な意味をもつ(
#
,
及び
参照)
。
型名
型変換を明示的に指定する場合,及び
$
,
又は
の実引数を指定する場合には,型の名
前を指定しなければならない。この型の名前は,
《型識別子》を使って指定してもよい。その《型識別子》は,構文的
に,その型のオブジェクト 又は 関数に対する宣言からそのオブジェクト 又は 関数の名前を省略したものとなる。
型識別子
3
型指定子列
抽象宣言子
型指定子列
3
型指定子
型指定子列
抽象宣言子
3
ポインタ演算子
抽象宣言子
直接抽象宣言子
直接抽象宣言子
3
直接抽象宣言子
仮引数宣言節
0
修飾子列
例外指定
直接抽象宣言子
S
定数式
T
抽象宣言子
《抽象宣言子》は,その中のある位置に識別子を書き加えると,構文的に,宣言における《宣言子》となる。その位
置は,一意に特定することができる。
《抽象宣言子》で指定される型は,この仮想的な識別子がもつことになる型と
同じ型とする。
例
''
!
''
!
!S*T
''
!S*T
! S*T
''
!* S*T
!
''
!
!
''
!
これらの例は,それぞれ,
:;
という型,
:
へのポインタ
;
という型,
:
へのポインタ三つから
なる配列
;
という型,
:
三つの
をもつ配列へのポインタ
;
という型,
:
へのポインタを返す( 仮引数
のない)関数
;
という型 及び
:3 %
型の仮引数をもち
を返す関数へのポインタ
;
という型となる。
型は,
1
3
指定子(
)
)を使って,型を指定することもできる( 通常,このほうが簡単にできる。)
。
あいまい性の解決
関数形のキャストと 宣言との間の類似性から起こるあいまい性(
(
参照)は,宣言の文
脈においても起こりうる。この文脈では,仮引数名を囲む括弧を冗長にもった関数宣言と,関数形のキャストを初期
化子としてもつオブジェクト宣言との間の選択となる。
(
に示したあいまい性に対しては,宣言となる可能性があ
る構文は宣言とすることで解決法とする。
参考
関数形でないキャストを使うこと,初期化を示すのに
:
%;
と記述すること,又は 仮引数名を囲む冗長
な括弧を除去することによって,宣言を明示的にあいまい性のないものにすることができる。
例
F
Q
F &
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
R&
Q
F
&
''
関数宣言
F
&
''
関数宣言
F
&
''
オブジェクト宣言
F
$
%
&
''
オブジェクト宣言
R
関数形のキャストと型識別子との間で起こるあいまい性は,別の文脈においても起こりうる。そのあいまい性は,
関数形のキャスト式と 型宣言との間の選択に対して生じる。その解決策として,その構文が構文規則の文脈として
《型識別子》になる可能性がある場合には,
《型識別子》と考えることとする。
例
#
!&
!
$P
,
&
Q
%
-*&
!
&
''
生成位置指定の式
!ST &
''
生成型識別子
R
別の例を示す。
例
F
Q
!
R&
F
&
''
型識別子
FL
&
''
式
3
これは不適格
別の例を示す。
例
Q
$L &
''
式
$ &
''
型識別子
3
これは不適格
R
別の例を示す。
例
Q
L &
''
式
L&
''
型識別子
3
これは不適格
R
《型名》が括弧で入れ子になっている場合,関数宣言の《仮引数宣言節》中で,又は 演算子
$
若しくは
の演算対象になっている《型識別子》の中で,別のあいまい性が起こる。この場合には,関数へのポインタ型の仮引
数の宣言か,又は 《宣言子識別子》を囲んだ冗長な括弧をもつ仮引数の宣言かという選択が行われる。その解決策
は,
《型名》を《宣言子識別子》ではなく,
《単純型指定子》と選択することとする。
例
7
Q
R&
7
Q
R
''
7 &
ではなく,
''
! 7
Q
R
となる。
7 &
Q
L &
''
エラー
3
L
を関数ポインタに変換できない。
&
''
B>
R
別の例を示す。
7
Q
R&
!7SL.T &
''
!7SL.T &
ではなく,
''
!!P 7PSL
.T
&
となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
宣言子の意味
宣言子の並びは,
《宣言指定子列》
(
)
)の後にあってもなくてもよい(
)
参照)。それぞれの
宣言子は,ただ一つの《宣言子識別子》をもつ。それが,宣言される識別子の名前となる。
《宣言子識別子》の中の
《修飾なし識別子》は,いくつかの特殊関数(
,
及び
#
参照)を宣言する場合,及び テンプレート特殊
化 又は 部分特殊化(
)
)を宣言する場合を除き,単純な《識別子》としなければならない。
《宣言子識別子》には,
次のいずれかの場合を除き,修飾を付けてはならない。
―
あるクラスの外で,そのクラスの,メンバ関数(
*
) 又は 静的データメンバ(
*
)を定義する場合
―
ある名前空間の外で,その名前空間の 関数メンバ 又は 変数メンバを定義するか,又は 明示的具現化を行
う場合
―
ある名前空間の外で,その名前空間に関係する,それ以前に宣言した明示的特殊化の定義を行う場合
―
随伴の相手のクラス 又は 名前空間のメンバを随伴関数として宣言する場合(
参照)
《宣言子識別子》に修飾を付ける場合,その宣言は,その修飾子が参照するクラス 又は 名前空間の先行して宣言した
メンバを参照しなければならず,そのメンバは,その《宣言識別子》の《入れ子名前指定子》によって指名されたク
ラス 又は 名前空間の有効範囲の中に《
!
宣言》によって導入されていてはならない。
参考
その修飾子が大域的な有効範囲解決演算子
33
の場合,
《宣言子識別子》は,大域的名前空間有効範囲の
中で宣言された名前を参照する。
,
,
,
,
,
,
,
又は
の各指定子は,
《初期化
宣言子並び》中の《宣言子識別子》のそれぞれに直接適用される。それぞれの《宣言子識別子》に指定される型は,
《宣言指定子列》 及び その《宣言子》の両方に依存して決まる。
したがって,ある識別子の宣言は,次の形式となる。
ここで,
は宣言指定子列,
は宣言子とする。次の段落では,このような宣言によって,その中に含まれる《宣言
子識別子》に対し指定した型を決めるための再帰的手続きを示す。
まず,
《宣言指定子列》から型を決める。
この宣言では,
《宣言指定子列》の
から型
:
;
を決める。
例
宣言
&
この例では,型指定子
及び
から,型
: !3
;
(
)#
)と決まる。
宣言
:
;
において,
が純粋な識別子の場合,その識別子の型は,
:
;
とする。
宣言
:
;
において,
が,
:
;
という形式の場合,
《宣言子識別子》に含まれる型は,
:
;
という宣言
の中の《宣言子識別子》に含まれる型と同じとする。括弧は,その中の《宣言子識別子》の型を変えないけれど も,
複雑な宣言子間の結合のしかたを変えることがある。
ポインタ
宣言
:
;
において,
が,
:!
0
修飾子列
;
という形であって,宣言
:
;
の中の識
別子の型が
:
派生宣言子型並び
;
である場合,
の識別子の型は,
:
派生宣言子型並び 及び 《
0
修飾子列》の付い
た
へのポインタ
;
とする。
《
0
修飾子》は,そのポインタに適用されるが,それが指すオブジェクトには適用され
ない。
参考
派生宣言子型は,複合型(
*
)のうち,クラスに関係する型を除く型とする。派生宣言子型並びは,
派生宣言子型を指す宣言子の並びとする。
例
%
L.
,
!
%
0
!
%
!!&
!
!
%
0&
この例では,
を整数定数,
を整数定数へのポインタ,
を整数定数へのポインタ定数,
を整数
定数へのポインタへのポインタ,
<
を整数,
を整数へのポインタ 及び
を整数へのポインタ定数とし
て,それぞれ宣言している。
,
及び
は,その初期化の後では,値を変更できない。
の値は,
変更でき,
のポイントするオブジェクトも変更できる。いくつかの正しい操作の例を,次に示す。
%
&
!
%
&
))&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
%
&
%
&
%
0&
不適格な操作の例を,次に示す。
%
L&
''
エラー
))&
''
エラー
!
%
+&
''
エラー
%
0&
''
エラー
))&
''
エラー
%
&
''
エラー
%
0&
''
エラー
これらは,
として宣言されたオブジェクトを変更しようとしたために,又は 後で
0
修飾なしのポ
インタを使ってそれを変更することを許すことになるために,認められない。後者の例を次に示す。
!
%
0&
''
B>3
ただし ,
が
をポイントするようになる。
''
上の
%
0
がエラーのため。
!
%
/&
''
の強引な変更である。
#)
及び
#
も参考になる。
参考
参照へのポインタは,存在しない(
参照)
。ビットフィールド(
*(
)のアドレスを取ることはで
きないので,ポインタがビットフィールド を指すことはない。
参照
宣言
:
;
において,
が,
:0
;
という形式であって,
:
;
という宣言の中の識別子の型が,
:
派生宣言子型並び
;
の場合,
の識別子の型は,
:
派生宣言子型並びが付いた
への参照
;
となる。ある
0
修飾
子が,型定義(
)
)の使用 又は テンプレート実引数(
)の使用によって導入された場合(これらの場合,
0
修飾子は無視される。)を除き,
0
修飾子付きの参照は,不適格とする。
例
0
6&
6
%
*&
''
不適格
3
非
の参照を
''
右辺値で初期化している。
この例において,
の型は,
:
への参照
;
となり,
:
への
の付いた参照
;
とはならない。
参考
参照は,オブジェクトの名前と想定してもよい。
:0
修飾付きの
0
3
への参照
;
という型を指定した宣言子は,不適格とする。
例
0
Q
)%
*(LM&
R
''
(((
%
.&
&
この例は,
を
の参照仮引数として宣言しており,
を呼び出すと,
に
*(LM
が加算される。
S+.T&
''
(((
0
Q
ST&
R
''
(((
* %,&
この例は,
を整数への参照を返す関数と宣言しており,
* %,
は,
の第
要素に
,
を代入する。
もう一つの例を示す。
Q
!
&
R&
!
&
!0
''
は,ポインタへの参照となる。
Q
V
%
&
%
&
%
.&
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
Q
!
%
&
&
R
この例では,
を
へのポインタの参照と宣言しているので,
は,
の値をゼロにする(
#
も
参照)
。
参照が記憶域を必要とするか否かについては,規定しない(
)
参照)
。
参照への参照,参照からなる配列 又は 参照へのポインタというものは,存在しない。参照の宣言には,次のいず
れかの場合を除き,
《初期化子》
(
#
)がなければならない(
参照)
。
―
その宣言が,明示的に
?
指定子(
)
)を含む場合
―
その宣言が,クラス宣言の中のクラスメンバ宣言(
*
)である場合
―
その宣言が,仮引数 又は 返却値型(
#
)の宣言である場合
参照は,正当なオブジェクト 又は 関数を参照するように初期化しなければならない。
参考
特に,適格に定義されたプログラムには,空の参照は,ありえない。このような空の参照を作る唯一の
方法は,空ポインタの参照をはずして得たオブジェクトにそれを結合することであって,その場合の挙動
は,未定義となるからである。参照は,ビットフィールドと直接結合することはできない(
*(
参照)
。
メンバへのポインタ
宣言
:
;
において,
が次の形式であったとする。
33
入れ子名前指定子
!
0
修飾子列
#L
《入れ子名前指定子》がクラス名を指していて,宣言
:
;
の識別子の型が
:
派生宣言子型並び
;
となる場合,
の識別子の型は,
:
型
の《入れ子名前指定子》のクラスのメンバへの派生宣言子型並び 及び 《
0
修飾子列》が付
いたポインタ
;
とする。
例
5
Q
3
&
&
R&
J&
533!
%
0533&
533!
%
0533&
533!
&
J33!
&
この例では,
を型
の
5
のメンバへのポインタ,
を型
の
5
のメンバへのポインタ,
を型
の
5
のメンバへのポインタ,
を
型の
J
へのポインタと,それぞれ宣言している。
の宣言は,
5
が型
のメンバをもたない場合でも,適格とする。同様に,
の宣言は,
J
が不
完全型の場合でも,適格とする。
及び
は,次のように使うことができる。
5
&
''
(((
(!
%
,&
''
,
を
の整数メンバに代入する。
(!
, &
''
の関数メンバを実引数
,
で呼び出す。
メンバへのポインタは,クラスの静的メンバ(
*
),参照型のメンバ 又は
:0
;
を指してはならない(
#
及び
##
参照。)
。
参考
:
メンバへのポ インタ
;
という型は,
:
ポインタ
;
の型とは異なっている。すなわち,メンバへのポイン
タは,メンバへのポインタという宣言子の構文規則によってだけ宣言されるのであって,ポインタの宣言
子の構文規則によって宣言されない。
:
メンバへの参照
;
という型は,
"##
にはない。
配列
宣言
:
;
において,
が次の形式であったとする。
S
定数式
T
宣言
:
;
の識別子の型が
:
派生宣言子型並び
;
となる場合,
の識別子の型は,配列型とする。
は,その配
列の要素型と呼ぶ。この型は,参照型,型
(
0
修飾付きを含む。),関数型 又は 抽象クラス型であってはなら
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
ない。
《定数式》
(
#*
)がある場合,それは,汎整数定数式とし,その値は,正の値でなければならない。その《定
数式》は,配列の上限( 含まれる要素の数)の指定となる。
《定数式》の値が
のとき,配列の要素数は,
要素と
なり,添字は,
から
となる。
の識別子の型は,
:
派生宣言子型並びが付いた,
型
要素の配列
;
となる。
配列型のオブジェクトは,型
の
個の部分オブジェクトから成る,空でなく連続に割当てた集合をもつことにな
る。
《定数式》が省略された場合,
の識別子の型は,
:
派生宣言子型並びが付いた,
型の要素数未知の配列
;
とな
り,不完全オブジェクト型とする。
:
派生宣言子型並びが付いた,
型
要素の配列
;
と
:
派生宣言子型並びが付い
た,
型の要素数未知の配列
;
とは,別の型とする(
*
参照)。
:
《
0
修飾子列》付きの
型
要素の配列
;
の型
は,
:
《
0
修飾子列》が付いた
型を
要素もつ配列
;
とする。
:
上限不明の配列
;
についても同様とする。
例
6S/T
66S+TS*T&
6
76&
''
\\
/
個からなる配列
ZZ
という型
66
766&
''
\\
*
個からなる配列を
+
個もつ配列
ZZ
''
という型
参考
:
《
0
修飾子列》が付いた
型を
要素もつ配列
;
の型は,
0
修飾型とする。そういう配列は,明示的
に
宣言(
)#
)をしなければ内部結合となり,
#
に規定する初期化をしなければならない。
配列は,基本型のいずれか(
を除く。),ポインタ,メンバへのポインタ,クラス,列挙型 又は ほかの配列か
ら構築することができる。
:
の配列
;
という指定が複数続いた場合,多次元の配列が生成される。それぞれの配列の上限を指定する定数式のう
ち,最初の次元の定数式だけは省略することができる。
参考
配列型の関数仮引数に対して,この省略を使うと効果がある。また,配列が外部に存在し,その記憶域
を割り付ける定義が別のところで指定されている場合にも効果がある。
ある宣言に引き続いて《初期化子》がある場合にも,最初の《定数式》を省略することができる(
#
参照)
。その場
合の上限は,初期化する要素の個数(
#
)
(
とする。)から計算され,
の識別子の型は,
:
型
個の配列
;
と
なる。
例
SL,T
!SL,T&
この例は,
5
型数値の配列 及び
5
型数値へのポインタの配列を宣言している。もう一つの例を示す。
*S*TS/TS,T&
この例は,整数型の
の次元数の
次元配列を宣言している。詳細に言うと,
*
は,
項目から
なる配列となり,その各項目は,
個の配列からなる配列となり,その前者の配列は,
個の整数からなる
配列となる。
*
,
*ST
,
*STST
及び
*STSTST
という式は,いずれも,式の中で使うことが
できる。
参考
配列型の左辺値に影響を与える変換については,
で規定する。配列型のオブジェクトの形式を変更
することはできない(
参照)
。
添字演算子
ST
は,クラスに対してすでに宣言されている場所を除き(
##
参照),
8LS8+T
が
!8L )8+
と同じになるように解釈される。
)
演算子に適用される変換規則によって,
8L
を配列とし ,
8+
を整数としたとき,
8LS8+T
は,
8L
の
8+
番目のメンバを参照する。したがって,見かけは非対称だが,添字付けは,可換な操作となる。
多次元配列に対しても,一貫した規則に従う。
8
を
次元配列とし,次元数を
"
×
×
×
としたとき,式中に
現れる
8
は,次元数
×
×
の
次元の配列へのポインタに変換される。このポインタに,添字付けの結果
として明示的であれ暗黙的であれ,
!
演算子が適用される場合,その結果は,
次元配列を指すものとなるが,
それ自体は,即座にポインタに変換される。
例
S*TS/T&
この例を考える。ここで,
は,
の整数配列となる。式中に
が現れたとき,それは,
個の整数から
なる配列(
個の中の最初のもの )へのポインタに変換される。式
ST
は,
!)
と同等となるが,ま
ず
がポインタに変換され,次に
)
が
の型に変換される。その際に,ポインタの指すオブジェクト(
個の整数からなる配列)の長さに対する
の乗算が行われる。その結果に,加算 及び 間接参照を適用し
て,
(
個の整数からなる)配列が得られる。その次に,それは,先頭にある整数を指すように変換される。
さらに添字がついている場合には,さらに同じことが繰り返されるが,その場合の結果は,整数となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
参考
このことは,
"##
における配列が,行方向に( つまり最後の添字から変化するように )格納されるこ
とから生じている。宣言における先頭の添字は,配列が使う記憶域の量を決定する助けになるが,添字計
算における役割はない。
#
関数
宣言
:
;
において,
が次の形式であったとする。
仮引数宣言節
0
修飾子列
例外指定
宣言
:
;
に含まれる《宣言子識別子》の型が
:
派生宣言子型並び
;
となる場合,
の《宣言子識別子》の型は,
:
《仮引数宣言節》
及び 《
0
修飾子列》
が付いた,
を返す派生宣言子型並び付きの関数
;
とする。この形式
の型は,関数型とする。
仮引数宣言節
3
仮引数宣言並び
(((
仮引数宣言並び
(((
仮引数宣言並び
3
仮引数宣言
仮引数宣言並び
仮引数宣言
仮引数宣言
3
宣言指定子列
宣言子
宣言指定子列
宣言子
%
代入式
宣言指定子列
抽象宣言子
宣言指定子列
抽象宣言子
%
代入式
《仮引数宣言節》によって,指定可能な実引数が決まり,その関数を呼び出したときの実引数の処理が決まる。
参考
《仮引数宣言節》は,関数呼出しに指定した実引数を変換するために使われる(
#
参照)
。
《仮引数宣言節》が空の場合,その関数は実引数を受け取らない。仮引数並びが
の場合,空の仮引数並びと同
等とする。この特殊ケースを除き,
は,仮引数の型になってはならない(ただし,
から派生する型,
!
などはなりうる。)
。
《仮引数宣言節》が省略記号で終了している場合,実引数の数は,指定してある仮引数の数と同
じかそれ以上でなければならない。構文的に正しい場所では,
:
(((;
は,
:(((;
と同じ意味とする。
例
!
((( &
この例は,実引数の数 及び 型を可変にして呼び出すことができる関数を宣言している。
Y
Y &
Y%U
%UY
&
ただし ,第
実引数は,
!
に変換できなければならない。
参考
標準ヘッダ
には,省略記号を使って渡された実引数をアクセスする機構が 含まれている
(
#
及び
)
参照)
。
一つの有効範囲内で,複数の異なる関数に対し同一の名前を使うことができる。それを関数多重定義という(
参照)
。ある仮引数並びをもつ関数に対するすべての宣言は,返却値の型 並びに 仮引数の数 及び 型の両方について,
完全に一致していなければならない。その際,省略記号の有無は,関数型の一部分として考える。関数の型は,一連
の規則によって決める。まず,それぞれの仮引数の型を,それ自身の《宣言指定子列》 及び 《宣言子》によって決め
る。各仮引数の型が決まった後,型
:
の配列
;
又は 型
:
を返す関数
;
の仮引数は,それぞれ,
:
へのポ インタ
;
又は
:
を返す関数へのポインタ
;
に調整する。仮引数の型の並びが出来上がった後,関数の型を決めるために,そ
れらに対して種々の変形を施す。仮引数の型を修飾するすべての
0
修飾子は,削除する。
例
!
は,
!
になる。
このような
0
修飾子は,関数の本体にある仮引数の定義にだけ影響し,関数の型には影響しない。
《記憶域種別指定
子》が仮引数型を修飾している場合,その指定子は,削除する。
例
!
は,
!
になる。
このような《記憶域種別指定子》は,関数の本体にある仮引数の定義にだけ影響し,関数の型には影響しない。こう
して変形された仮引数の型の並びを,その関数の仮引数型並びとする。
注
構文規則が規定するように,
"#
修飾子は,関数の返却値型の重要な構成要素である。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
《
0
修飾子列》が関数型に書いてあってよいのは,非静的メンバ関数の関数型,メンバへのポ インタで参照して
いる関数型 又は 関数の型定義の宣言の中で最上位にある関数型だけとする。関数の宣言子にある《
0
修飾子列》の
効果は,関数型の先頭に
0
修飾子を加えるのとは異なる。つまり,それは,
0
修飾付きの関数型を作らない。事実,
型の決定のいかなる時点でも,
0
修飾付きの関数型ができた場合,そのプログラムは不適格とする。
例
9 &
F
Q
9
&
''
不適格
3
と異なる。
R
返却値型,仮引数型並び 及び 《
0
修飾子列》は,関数型の一部となるが,省略時実引数(
(
) 及び 例外指定
(
#
)は,関数型の一部にならない。
参考
関数型の検査は,関数へのポインタ,関数への参照 及び メンバ関数へのポ インタのいずれかに対する
代入 及び 初期化のときに行われる。
例
9<?8!
この例は,三つの指定された型の実引数を受け入れ,
(
)#
)を返却する関数を宣言している。
ある仮引数の型が,
:
の上限不明の配列へのポインタ
;
という形の型 又は
:
の上限不明の配列への参照
;
という
形の型を含む場合,そのプログラムは不適格とする
。関数の返却値の型は,関数 又は 配列としてはならないが,
これらへのポインタ 又は 参照を返却値の型にしてもよい。関数から成る配列はありえないが,関数へのポインタから
成る配列はありうる。型を,返却値の型 又は 仮引数の型の中で定義してはならない。関数定義における仮引数の型
及び 返却値の型は,その関数定義がクラスのメンバ指定の中に入れ子になっていない場合(そのクラス内で定義され
ている入れ子クラスの中での定義も含む。),不完全なクラス型(
0
修飾付きのこともある。)であってはならない。
関数型の型定義は,関数を宣言するのに使ってもよいが,関数を定義するのに使ってはならない(
参照)
。
例
9 &
9
&
''
B>3
と等価
9
Q
R&
''
不適格
Q
R&
''
B>3
の定義
《
0
修飾子列》を含む宣言子をもつ関数型の型定義は,非静的メンバ関数に対する関数型を宣言するため,メンバへ
のポインタが参照する関数型を宣言するため 又は 他の関数の型定義の宣言の最上位の関数型を宣言するため にしか
使ってはならない。
例
9<7
&
9<7
&
''
不適格
3
メンバ関数の宣言ではない。
F
Q
9<7
&
''
B>
R
9<7
F33!
%
0F33&
''
B>
仮引数名として,識別子を付けてもよいし ,付けなくてもよい。それが関数定義(
)にある場合,それが仮引
数の名前となる。
参考
特に,関数定義において仮引数名を指定するかしないかは任意とするし ,ある仮引数に対して,個々の
関数宣言 及び 関数定義で使う名前を,同じにする必要はない。関数宣言が関数定義ではない場合であっ
て,関数宣言に仮引数名がある場合,関数宣言子の終点で仮引数名の有効範囲から外れるので,
《仮引数宣
言節》の外側でその仮引数名を使うことはできない(
参照)
。
例
!
!
!
!
!
!
&
注
ただし,
《ポインタ
,
配列の列》が付いた
という型の仮引数の場合を除く。ここで,
は
の上限不明の配列へのポインタ
とし,
《ポインタ
,
配列の列》とは,
へのポインタ
及び
の配列
という派生した宣言子型を任意に混合した列とする。この例外規則は,
関数の仮引数に対して適用されるし,仮引数が関数へのポインタ 又は メンバ関数へのポインタである場合には,その関数の仮引数に対
しても,順次適用される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
この例では,順にそれぞれ,整数
,整数へのポインタ
,実引数がなく
を返す関数
,
の実引数
を必要とし
へのポインタを返す関数
,二つの
へのポインタの実引数を必要とし
を
返す関数へのポインタ
,及び
の実引数を必要とし
を返す関数へのポインタを返し
の実引
数を必要とする関数
を,宣言している。
と
とを比較してみるのが役に立つ。
!
の結
合は,
!
となる。宣言が示唆するように,また,式中の二つの同じ構文が要請するように,まず
関数
を呼び出し,次に,結果(ポインタ)を介した間接参照を使って
が得られる。
!
!
!
という宣言子においては,関数へのポインタを介した間接参照を使って関数を得
るためには,括弧が余分に必要となる。その後,その関数が呼び出される。
参考
関数の返却値の型が複雑な場合,型定義を使うのが便利なことがある。例えば ,上の
は,次のよ
うに宣言してもよかった。
<9G7A7 &
<9GA7!
&
(
省略時実引数
式を仮引数宣言に指定した場合,この式が省略時実引数として使われる。省略時実引数は,対
応する実引数がない呼出しの場合に使われる。
例
%
*
%
M &
この例は,型
の実引数を
個,
個 又は
個使って呼び出すことができる関数を宣言している。次の
種類の呼出しができる。
L
+ &
L &
&
後ろの二つは,それぞれ,
1
,
,
1
,
と同等になる。
省略時実引数の式は,関数宣言の《仮引数宣言節》 又は 《テンプレート仮引数》
(
)の中でしか指定してはな
らない。
《仮引数宣言節》で指定した場合,
《仮引数宣言》の中の《宣言子》 又は 《抽象宣言子》の中で指定してはな
らない。
非テンプレート関数の場合,省略時実引数を,同じ有効範囲の中の後続の関数宣言の中で付け加えることができる。
有効範囲が異なる複数の宣言は,完全に異なる省略時実引数をもつ。すなわち,有効範囲の内側での宣言が,外側の
有効範囲の宣言から省略時実引数を得ることはないし ,その逆もない。関数宣言において省略時実引数をもつ仮引数
があれば ,その仮引数に後続する仮引数は,すべて,その関数宣言 又は それに先行する関数宣言の中で,省略時実
引数が指定されていなければならない。省略時実引数は,後続の宣言で再定義してはならない(それが,同一の値で
あっても不可とする。)
。
例
&
%
, &
Q
* &
''
B>3
* ,
を呼び出す。
%
L
&
''
エラー
3
取り囲む有効範囲の省略時
R
''
実引数は使用しない。
Q
&
''
省略時実引数はない。
M &
''
エラー
3
実引数の数が不適格。
%
/ &
''
B>
M &
''
B>3
M
/
を呼び出す。
%
/ &
''
エラー
3
同じ値であっても省略時
R
''
実引数の再定義はできない。
Q
- &
''
B>3
-
,
を呼び出す。
R
インライン関数を異なる複数の翻訳単位で定義する場合,それぞれの翻訳単位の最後の時点では,省略時実引数の累
積結果の集合は,同じにしなければならない(
参照)
。
注
このことは,省略時実引数が,例えば,関数へのポインタ,関数の参照 又は
&%
宣言内に現れてはならないことを意味する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
省略時実引数の式は,暗黙的に仮引数の型に変換される(
参照)
。省略時実引数の式には,その仮引数の型をもつ
変数を宣言する場合の初期化子の式に対するのと同様に,コピー初期化の意味規則(
#
)を使う際の制約を受ける。
式中の名前を結合し,意味規則の制約を検査するのは,省略時実引数式が現れた場所で行う。関数テンプレート 及び
クラステンプレートのメンバ関数における省略時実引数式に対し ,名前検索 及び 意味規則の制約の検査を,
)
で規定するとおりに行う。
例
次の例で,
は,値
+
を使って呼び出される。
%
L&
&
%
&
''
省略時実引数は,
33
となる。
Q
%+&
Q
%
*&
&
''
33
となる。
R
R
参考
メンバ関数の宣言において,省略時実引数の式の中の名前は,
に規定するように検索される。
で規定するように,省略時実引数の式の中の名前に対して,アクセス検査が適用される。
クラステンプレートのメンバ関数の場合を除き,クラス定義の外側に現れるメンバ関数定義の中の省略時実引数は,
そのクラス定義の中のメンバ関数宣言に書かれた省略時実引数の集合に追加される。クラステンプレートのメンバ関
数の場合には,その省略時実引数は,クラステンプレートの中のメンバ関数の最初の宣言で指定しなければならない。
例
7
Q
%
* &
%
OO &
R&
733
%
*
''
エラー
3
省略時実引数は,すでに
Q
R
''
クラス有効範囲内で指定されている。
733
%
NN
''
この翻訳単位では,
733
は,
Q
R
''
実引数なしで呼び出すことができる。
局所変数は,省略時実引数の式内に使ってはならない。
例
Q
&
%
&
''
エラー
''
(((
R
キーワード
は,メンバ関数の省略時実引数に使ってはならない。
例
6
Q
6!
%
Q
R
''
エラー
R
省略時実引数は,その関数が呼び出される度に評価される。関数実引数の評価の順序は,規定しない。したがって,
関数の仮引数は,たとえそれらが評価されなくても,省略時実引数の式の中に使ってはならない。省略時実引数の式が
現れる前に宣言された関数の仮引数は,有効範囲内にあり,名前空間 及び クラスメンバ名を隠ぺいすることがある。
例
&
%
&
''
エラー
3
仮引数
を省略時実引数として
''
使っている。
<&
<
%
<+ &
''
エラー
3
仮引数
<
がある。
%
$ &
''
エラー
3
仮引数
を省略時実引数に使っている。
同様に,非静的メンバは,たとえそれが評価されなくても,省略時実引数の式に使ってはならない。ただし ,非静的
メンバが,クラスメンバのアクセス式(
##
)の識別子式として現れる場合,及び メンバへのポインタ(
#
)を
構成するために使われる場合には,使ってもよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
次の例における
533L
の宣言は,初期化子として使われている非静的メンバ
533
をもつオブジェク
トを供給されないので,不適格となる。
&
5
Q
&
L
%
&
''
エラー
3
非静的メンバ
を
''
省略時実引数に使用している。
+
%
&
''
B>3
533
を使用する。
&
R&
しかし,静的メンバ
533
をアクセスするのに,オブジェクトは構築されている必要はないので,
533+
という宣言は,意味がある。クラス,オブジェクト 及び メンバについては,
*
で規定する。
省略時実引数は,関数の型の一部としない。
例
%
. &
Q
%
L &
%
&
''
B>
.
の意味。
R
!L
%
0&
!+
%
0&
''
エラー
3
型の不一致。
関数の宣言を《
!
宣言》
(
)
)を使って導入した場合,その宣言に対する省略時実引数の情報も知られている。
その関数が,その名前空間内の後方で,省略時実引数を付け加えて再宣言された場合,その《
!
宣言》が有効範
囲内にある範囲で,再宣言した場所の後方のどこであっても,追加された実引数も知られている。
仮想関数の呼出し(
)は,そのオブジェクトを示すポインタ 又は 参照の静的な型によって決まる仮想関数の
宣言内にある省略時実引数を使用する。派生クラスにおける上書き関数は,それによって上書きされる関数から省略
時実引数を引き継ぐ ことはない。
例
6
Q
%
, &
R&
"
3
6
Q
&
R&
Q
"!
%
"&
6!
%
&
V &
''
B>3
V"33,
を呼び出す
V &
''
エラー
3
実引数の数が
"33
と不一致
R
関数定義
関数定義の形式は,次のとおりとする。
関数定義
3
宣言指定子列
宣言子
コンストラクタ初期化子
関数本体
宣言指定子列
宣言子
関数監視ブロック
関数本体
3
複合文
《関数定義》における《宣言子》は,
#
によって,次の形式をとる。
仮引数宣言節
0
修飾子列
例外指定
関数は,名前空間 又は クラス有効範囲の中でだけ,定義しなければならない。
例
完全な関数定義の簡単な例を,次に示す。
Q
%
2
3
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
2
3
&
R
ここで,
が《宣言指定子列》に,
が《宣言子》に,
'!
(((!'
が《関
数本体》になる。
《コンストラクタ初期化子》は,コンストラクタでだけ使われる(
及び
(
参照)
。
《
0
修飾子列》は,非静的メンバ関数の宣言,非静的メンバ関数の定義 又は メンバ関数へのポインタの一部とな
りえる(
*
参照)
。それは,関数の型の一部となる。
参考
使用されない仮引数には,名前がなくてもよい。
例
Q
Y
%
U4Y &
R
#
初期化子
《宣言子》には,宣言される識別子の初期値を指定することができる。その識別子は,初期化される
オブジェクト 又は 参照を指し示す。
#
の残りの部分で規定される初期化の処理は,実引数の式(
#
)をもつ関
数仮引数の初期化,返却値(
((
)の初期化など ,他の構文規則の文脈によって指定される初期化にも適用される。
初期化子
3
%
初期化子節
式並び
初期化子節
3
代入式
初期化子並び
初期化子並び
3
初期化子節
初期化子並び
初期化子節
名前有効範囲の中の自動変数,レジスタ変数,静的変数 及び 外部変数は,リテラル 並びに 宣言済みの変数 及び
関数を含む任意の式によって,初期化することができる。
例
&
%
+&
%
&
&
参考
省略時実引数の式に対しては,さらに制約がある(
(
参照)
。
静的オブジェクトを初期化する順序は,
(
及び
)
で規定している。
型
のオブジェクトのゼロ初期化とは,次のいずれかを意味する。
―
がスカラ型(
*
)の場合,そのオブジェクトに,ゼロを型
に変換した値を設定する。
―
が共用体でないクラス型の場合,各非静的データメンバ 及び 各基底クラスの部分オブジェクトをゼロ
初期化する。
―
が共用体型の場合,そのオブジェクトの先頭の名前付きデータメンバ
をゼロ初期化する。
―
が配列型の場合,各要素をゼロ初期化する。
―
が参照型の場合,初期化は行わない。
型
のオブジェクトの省略時初期化とは,次のいずれかを意味する。
―
が
"
互換でないクラス型(
*
)の場合,
の省略時コンストラクタが呼び出される(
に,アクセスで
きる省略時コンストラクタがないときは,その初期化は,不適格とする。)
。
―
が配列型の場合,各要素に対し省略時初期化を行う。
―
そうでない場合,そのオブジェクトをゼロ初期化する。
型
のオブジェクトの値初期化とは,次のいずれかを意味する。
注
このメンバは,
の要求に従うため,静的であってはならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
―
が利用者定義コンストラクタをもたないクラス型(
*
)の場合,
の各非静的データメンバ 及び 各基
底クラスの成分を,値初期化する。
―
が配列型の場合,各要素に対し値初期化を行う。
―
そうでない場合,そのオブジェクトをゼロ初期化する。
参照型の実体の省略時初期化 又は 値初期化を行おうとするプログラムは,不適格とする。
が
0
修飾付きの型の場
合,ゼロ初期化,省略時初期化 及び 値初期化を定義するためには,
の
0
修飾なしの版が使われる。
静的記憶域期間をもつオブジェクトは,プログラム開始時に,他のすべての初期化に先行してゼロ初期化されなけ
ればならない。
参考
ただし ,後で付加的な初期化が行われることもある。
《初期化子》の括弧の中が空(すなわち,
)のオブジェクトには,値初期化を行わなければならない。
参考
5
&
この例は,
《初期化子》の構文規則に,
が許されていないので,クラス
5
のオブジェクトの宣言ではな
く,クラス
5
を返す実引数なしの関数の宣言となる。
の形式は,他の初期化の文脈(
#
,
#
,及
び
(
参照)においては,許される。
非静的オブジェクトに《初期化子》の指定がなく,
(
0
修飾付きでもよいが )
"
互換でないクラス型( 又は その配
列)の場合,そのオブジェクトは,省略時初期化されなければならない。そのオブジェクトが
!
修飾付きの型の
場合,その基礎とするクラス型は,利用者宣言の省略時コンストラクタをもっていなければならない。そうでない場
合,非静的オブジェクトに《初期化子》の指定がなければ ,オブジェクト 及び その部分オブジェクト( 存在すれば )
は,不定の初期値をもつ
。オブジェクト 又は その部分オブジェクトのいずれかが
!
修飾された型である場
合,そのプログラムは,不適格とする。
静的メンバに対する《初期化子》は,そのメンバのクラスの有効範囲の中にある。
例
&
5
Q
&
&
R&
533
%
L&
533
%
&
''
533
%
533
初期化の形式( 括弧を使うか 又は
%
を使うか )は,一般的には有意な差異はないが,初期化される実体がクラス
型の場合には,重要な差異となる( 次を参照)。括弧付きの《初期化子》は,初期化する実体がクラス型のときに限
り,式の並びとしてもよい。
実引数を渡す場合,関数から戻る場合,例外を送出する場合(
#
),例外を処理する場合(
#
) 及び 波括弧
で囲まれた《初期化子並び》がある場合(
#
)に行われる初期化をコピー初期化と呼び,次の形式と同等とする。
%
&
<
式(
#
),静的キャスト式(
#*
),関数記法の型変換(
#
) 並びに 基底 及び メンバ初期化子(
(
)
の中で行われる初期化を,直接の初期化と呼び,次の形式と同等とする。
&
がスカラ型の場合,次の二つの形式は,同等とする。
%
Q
R&
%
&
《初期化子》の意味規則は,次のとおりとする。目的の型とは,初期化されるオブジェクト 又は 参照の型のこと
とし ,元の型とは,初期化子の式( 初期化子式と呼ぶ。)のもつ型のこととする。
《初期化子》が波括弧で囲まれてい
る場合 又は それが式の並びを括弧で囲った場合,元の型は,定義されない。
―
目的の型が参照型の場合については,
#
で規定する。
注
この規定は,
で囲まれた不完全な《初期化子並び》を使って初期化される自動記憶域期間の集成体オブジェクトについては,適用
されない(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
―
目的の型が
型の配列 又は
<
型の配列であって,
《初期化子》が文字列リテラルである場合につ
いては,
#
で規定する。
―
そうではなくて,目的の型が配列の場合については,
#
で規定する。
―
目的の型が,
(
0
修飾付きでもよいが,
)クラス型の場合,次のとおりに規定する。
そのクラスが集成体(
#
)であって,かつ,
《初期化子》が波括弧で囲まれた並びの場合につ
いては,
#
で規定する。
初期化が直接初期化である場合,又は コピー初期化であって,元の型の
0
修飾なしの版が目
的のクラスと同じ クラス 若し くは 目的のクラスの派生クラスの場合,コンストラクタを利用
する。適用可能なコンストラクタを列挙し(
参照),多重定義解決(
)を行って
最良のものを選択する。そうして選択されたコンストラクタを,初期化子式を実引数として呼
び出し ,オブジェクトを初期化する。適用可能なコンストラクタがない場合 又は 多重定義解
決があいまいとなった場合,その初期化は,不適格とする。
そうでない場合( つまり,コピー初期化であって上の条件でない場合),元の型から目的の型
へ 又は ( 変換関数が使われていれば )その派生型へ変換できるように,利用者定義の変換の
手続きを列挙し(
参照),多重定義解決(
)を使って最良のものを選択する。そ
の変換が実行できない場合 又は あいまいである場合,初期化は不適格とする。そうして選択
した関数を,初期化子式を実引数にして呼び出す。その関数がコンストラクタの場合,元の型
の一時変数を初期化する。呼出しの結果(コンストラクタの場合には,一時変数になる。)を,
上記の規則に従って,コピー初期化の目的になっているオブジェクトを直接初期化するために
使用する。その場合,処理系は,初期化されるオブジェクトに中間結果を直接作ることによっ
て,直接初期化に関するコピー動作を削除することが許されている(
及び
参照)
。
―
上のいずれでもない場合,元の型が(
0
修飾付きでもよい。)クラス型のとき,変換関数を利用する。適
用可能な変換関数を列挙し(
#
参照),多重定義解決(
)を使って最良のものを選択する。そ
うして選択された利用者定義変換を呼び出し ,初期化子式を,初期化されるオブジェクトに変換する。変
換が実施できない場合 又は あいまいな場合,初期化は不適格とする。
―
更に,上のいずれでもない場合,初期化されるオブジェクトの初期値は,初期化子式の( 変換されていて
もよい)値とする。標準変換(
)を必要に応じて利用し,初期化子式を目的の型の
0
修飾なしの版に変
換する。ここでは,利用者定義変換は,利用しない。変換が実行できない場合,初期化は不適格とする。
参考
二つの
0
修飾子
及び
に依存せず,型
:
;
の式は,型
:
;
のオブジェクト
を初期化することができる。
&
%
&
%
&
#
集成体
次のいずれをももたない配列 又は クラス(
*
)を,集成体と呼ぶ。
―
利用者宣言のコンストラクタ(
)
―
非公開 又は 限定公開の非静的データメンバ(
)
―
基底クラス(
)
―
仮想関数(
)
集成体が初期化される場合,その《初期化子》は,その集成体のメンバに対する《初期化子節》を添字の昇順 又は
メンバの順にコンマで区切って並べ,波括弧で囲んだ《初期化子節》を含んでもよい。集成体が部分集成体を含む場
合,この段落の規則は,部分集成体のメンバにも再帰的に適用する。
例
6
Q
&
"
Q
&
&
R
&
R
%
QL
Q+
*R
R&
この例では,
(
が
に,
((
が
に,
((
が
に初期化される。
集成体がクラスの場合,波括弧で囲まれていない単一の式によって初期化してもよい(
#
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
大きさが不明な配列は,
個の《初期化子》を波括弧で囲んだ《初期化子並び》で初期化した場合( ここで
は,
正の値とする。),
要素をもつ配列として定義される(
参照)
。
例
ST
%
Q
L
*
/
R&
この宣言には,大きさの指定がないが《初期化子》が三つあるので,
を三つの要素からなる一次元配
列として宣言し初期化する。
空の《初期化子並び》
を,大きさが不明な配列の《初期化子》として使用してはならない。
静的データメンバは,集成体を初期化する場合には,クラスメンバと見なさない。
例
6
Q
&
&
&
R
%
Q
L
+
R&
この例は,二つ目の《初期化子》の
は,静的データメンバ
633
を初期化するのではなく,
(
を初
期化する。
《初期化子》の個数が,初期化するメンバ数 又は 要素数を超える場合,その《初期化子並び》は,不適格とする。
例
SMT
%
Q
ZZ
ZZ
ZZ
ZZ
.
R&
''
エラー
この例は,不適格となる。
集成体のメンバ数より《初期化子》の個数のほうが小さい場合,明示的に初期化されなかった各メンバは,値初期
化(
#
)によって初期化される。
例
F
Q
&
!
&
&
R&
F
%
Q
L
YY
R&
この例は,
(
を
に,
(
を
YY
に,
(
を
の形式の式の値( すなわち,
)に初期化
する。
集成体メンバが空のクラスのときの《初期化子》は,空の《初期化子並び》
の形式としなければならない。
例
FQ
R&
6
Q
F
&
&
R
%
Q
Q
R
*
R&
空の《初期化子並び》は,あらゆる集成体の初期化に使ってもよい。集成体が空のクラスでない場合,集成体の各メ
ンバは,
の形式(
#
)の値を使って初期化しなければならない。ここで
は,初期化されないメンバの型と
する。
不完全な 又は 空の《初期化子並び》のために,参照型のメンバが初期化されなかった場合,そのプログラムは不
適格とする。
多次元配列を初期化するとき,
《初期化子》は,配列の最後( 最右)の添字が最も速く変化するように要素を初期化
する。
例
S+TS+T
%
Q
*
L
M
+
R&
この例は,
S.TS.T
を
,
S.TSLT
を
,
SLTS.T
を
,そして
SLTSLT
を
に初期化する。一方,
SMTS*T
%
Q
Q
L
R
Q
+
R
Q
*
R
Q
M
R
R&
この例は,
の(
次元配列とみなして )第
番目の列を初期化し ,残りは,
になる。
《初期化子並び》から波括弧を省くことができる場合がある。
《初期化子並び》が左波括弧で始まる場合,それに
引き続くコンマ分離の《初期化子》の並びが,一個の部分集成体の構成メンバを初期化していく。そのとき,メンバ
数よりも《初期化子》のほうが多い場合は,エラーとなる。これに対して,部分集成体に対する《初期化子並び》が
左波括弧で始まっていない場合には,並びの中から必要なだけの《初期化子》がその部分集成体のメンバの初期化に
使われた後,そこで残った《初期化子》が,その部分集成体が メンバとなっている集成体の中で,その次に位置して
いる部分集成体のメンバを初期化するのに使われる。
注
構文規則としては空の《初期化子並び》もありうるが,長さゼロの配列は,
には存在しない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
例
SMTS*T
%
Q
Q
L
*
/
R
Q
+
M
-
R
Q
*
/
,
R
R&
この例は,完全な波括弧付きの初期化になる。
,
及び
が,
の第
列
S.T
,すなわち,
S.TS.T
,
S.TSLT
及び
S.TS+T
を初期化する。次の
行は,
SLT
及び
S+T
をそれぞれ初期化する。
《初期化子》
のほうが早く終了するので,
S*T
の要素は,
という式によって,すなわち値
%
によって明示的
初期化をしたように初期化される。次の例では,
《初期化子並び》の波括弧を省略している。しかし ,その
《初期化子並び》は,上の例の完全波括弧付きの《初期化子並び》と同じ効果をもつ。
SMTS*T
%
Q
L
*
/
+
M
-
*
/
,
R&
の《初期化子》は,左波括弧で始まっているが,
S.T
の《初期化子》は,左波括弧で始まっていない。
したがって,
S.T
には,列の中の最初の三つの要素を使う。同様にして,次の三つの要素を
SLT
に,そ
の次の三つの要素を
S+T
に使う。
集成体メンバを《初期化子並び》の対応する《初期化子》を使って初期化する場合,すべての暗黙的型変換(
参
照)の適用が考慮される。その《初期化子》が メンバを初期化できる場合には,そのメンバの初期化が行われる。そ
うでない場合であって,その メンバが空でない部分集成体のときには,波括弧の省略と考え,その《初期化子》は,
その部分集成体の先頭のメンバを初期化するものと見なされる。
例
6Q
&
&
R&
"Q
6
L
+&
$&
R&
6
&
"
%
Q
M
R&
(L(
に対する《初期化子》の波括弧が省略されている。
(L(
は,
で初期化され,
(+
は,
で
初期化され,
($
は,
(
が返却する値(それが何であっても)によって初期化される。
参考
集成体の配列 又は 集成体のクラスは,利用者宣言コンストラクタ(
)をもつクラス型のメンバを
含むことがある。このような集成体オブジェクトの初期化は,
(
で規定する。
静的記憶域期間をもつ集成体を,波括弧で囲んだ《初期化子並び》を使って初期化する場合において,すべてのメ
ンバの初期化子式が定数式であって,集成体が
"
互換型であるときには,その初期化は,初期化の静的段階で行わな
ければならない(
(
参照)。そうでない場合,定数式によるメンバの初期化が,初期化の静的段階で行われるか,
動的段階で行われるかは,規定しない。
ある共用体を,波括弧で囲んだ《初期化子》を使って初期化する場合,波括弧の中には,その共用体の先頭のメン
バの《初期化子》だけを指定しなければならない。
例
Q
&
!
&
R&
%
Q
L
R&
%
&
%
L&
''
エラー
%
Q
.
YY
R&
''
エラー
%
Q
YY
R&
''
エラー
参考
上で述べたように,ある共用体のメンバに対する《初期化子》を囲む波括弧は,その共用体が他の集成
体のメンバである場合には,省略してもよい。
#
文字配列
文字型の配列(ここでは,単なる
,
,
のいずれでもよい。)は,
《文字列リテラル》
(括弧で囲まれていてもよい。)を使って初期化することができる。
<
型の配列は,
《ワイド 文
字列リテラル》
( 括弧で囲まれていてもよい。)を使って初期化することができる。
《文字列リテラル》の連続する文
字が,その配列の各メンバを初期化する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
ST
%
YF
U4Y&
この例は,
《文字列リテラル》で初期化される文字配列を示す。
4
も一つの文字であり,さらに
4.
が付
加されるので,
$
は,
となる。
配列要素の個数より多い《初期化子》があってはならない。
例
SMT%YY&
''
エラー
この例は,暗黙的に最後に付加される
4.
を入れる余地がないので,不適格となる。
#
参照
0
,すなわち,
:
型
への参照
;
(
)と宣言した変数は,オブジェクト,関数 又は
に変換可能
なオブジェクトのいずれかによって初期化しなければならない。
例
&
Q
&
0
%
&
''
は,
を参照する。
%
L&
''
の値は,
L
になる。
!
%
0&
''
は,
を指す。
0
%
&
''
は,
の参照するもの,つまり
を,参照する。
0
%
&
''
は,関数
を参照する。
&
''
関数
を呼び出す。
S*T&
0 S*T
%
&
''
は,配列
を参照する。
SLT
%
&
''
SLT
を更新する。
R
参照は,初期化した後で他のオブジェクトを参照するように変更することはできない。
参考
参照の初期化は,それへの代入とは異なる扱いとなる。
実引数渡し(
#
) 及び 関数の値の返却(
((
)は,それぞれ初期化の一つとする。
参照に対して《初期化子》を省略できるのは,仮引数宣言(
#
)の中,関数の返却値型の宣言の中,クラス宣言
の中のクラスメンバの宣言(
*
)の中,及び
指定子を明示的に使用した場合だけとする。
例
0
L&
''
エラー
3
初期化がない。
0
+&
''
B>
:
;
及び
:
;
という二つの型があり,
が
と同じ型であるか,
が
の基底クラスである場合,
:
;
は,
:
;
と参照関係にあるという。
が
と参照関係にあり,
が
以上に
0
修飾されている
場合,
:
;
は,
:
;
と参照適合であるという。多重定義解決においては,
が
より多く
0
修飾され
ている場合,修飾付き参照適合と見なす(
参照)
。二つの型
及び
が参照関係 又は 参照適合にあるこ
とを使って参照の結合の正当性が決まり,しかも
が
の基底クラスである場合,
がアクセス不可(
)で
あるか,
の基底クラスとしてあいまい(
)であれば ,そのような結合を必要とするプログラムは,不適格と
する。
型
:
;
への参照は,型
:
;
の式を使って,次のように初期化される。
―
次のいずれかの条件が成り立つかを調べる。
初期化子式が左辺値(ただし ,ビットフィールド ではない。)であって,
:
;
が
:
;
と参照適合となる。
初期化子式がクラス型をもち(すなわち,
がクラス型である。),それを型
:
;
の左辺
値に暗黙的に変換することができる。ここで,
:
;
は,
:
;
と参照適合とする
。
( この変換は,適用可能な変換関数(
(
)を列挙し ,多重定義解決(
)を行って最
適なものを選ぶことによって,選択される。)
参照は,前者が成り立つとき,初期化子式の左辺値に結合され,後者が成り立つとき,変換の結果の左辺
値に結合される。両方の場合とも,参照は,初期化子に直接結合するという。
参考
通常の左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
),及
び 関数からポインタへの標準変換(
)は必要ないので,このような左辺値への直接結合が
行われるとき,それらの適用は,抑止される。
注
このことは,参照型を返す変換関数(
)を必要とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
%
+(.&
0
%
&
''
は,
を参照する。
0
%
&
''
は,
を参照する。
6
Q
R&
"
3
6
Q
R
&
60
%
&
''
は,
の
6
型部分オブジェクトを参照する。
60
%
&
''
は,
の
6
型部分オブジェクトを参照する。
―
そうでない場合,参照は,
ではなく,
の型としなければならない(すなわち,
は,
でなければならない。)
。
例
0
+
%
+(.&
''
エラー
3
左辺値でなく,参照が
でない。
%
+&
0
*
%
&
''
エラー
3
型が不一致で,参照が
でない。
初期化子式がクラス型
をもつ右辺値であり,
:
;
が
:
;
と参照適合である場合,
参照は,次のいずれかの方法で結合される(ど ちらが選択されるかは,処理系定義とする。)
。
参照は,右辺値が表現するオブジェクト(
) 又は そのオブジェクトの中の部分オ
ブジェクトに,直接結合される。
%
型
:
;
の一時変数を作り,コピーコンストラクタを呼び出して右辺値のオブジェク
ト全体をその一時変数にコピーする。参照は,その一時変数 又は 一時変数の中の部分オ
ブジェクトに結合される。
コピーが実際に行われても行われなくても,コピーのために使うコンストラクタは,呼出し可
能でなければならない。
例
6
Q
R&
"
3
6
Q
R
&
"
&
60
%
&
''
"
の右辺値の
6
型部分オブジェクトに
''
直接結合するか,又は
"
のオブジェクト
''
全体をコピーし ,参照をこのコピーの
''
部分オブジェクト
6
に結合するかの,
''
いずれかが行われる。
そうでない場合,型
:
;
の一時変数を作り,参照ではないコピー初期化についての規則
(
#
)を使い,それを初期化子式によって初期化する。その後,参照は,その一時変数に結合
される。
が
と参照関係にある場合,
は,
と同等 又は より多く
0
修飾されてい
なければならない。そうでない場合,プログラムは不適格とする。
例
0
+
%
+&
''
+
は,値
+(.
をもつ一時変数を参照する。
%
L&
0
%
&
''
エラー
3
型の修飾子が落ちている。
参考
参照に結合された一時変数の生存期間については,
に規定している。
*
クラス
クラスは,型の一つとする。クラスの名前は,その有効範囲内において《クラス名》
(
*
)となる。
クラス名
3
識別子
テンプレート識別子
《クラス名》を導入するには,
《クラス指定子》 又は 《詳述型指定子》
(
)#
)を用いる。クラスのオブジェク
トは,メンバ 及び 基底クラスのオブジェクトの列( 空であってもよい。)から成る。
クラス指定子
3
クラス先頭部
メンバ指定
注
明らかなことに,その参照の初期化がコピーコンストラクタ呼出しの第
実引数に対する初期化の場合,処理系は,無限の再帰呼出し
を回避するために,第
番目の選択(コピーではなく直接結合)を行わざるをえない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
クラス先頭部
3
クラスキー
識別子
基底節
クラスキー
入れ子名前指定子
識別子
基底節
クラスキー
入れ子名前指定子
テンプレート識別子
基底節
クラスキー
3
《クラス名》は,
《クラス名》が現れると即座に,宣言される有効範囲に加えられる。
《クラス名》は,クラス自身
の有効範囲にも加えられる( 補整クラス名と呼ぶ。)
。アクセス検査に当たっては,補整クラス名は,公開メンバ名で
あるかのように扱われる。
《クラス指定子》のことを,クラス定義とも呼ぶ。クラスは,そのクラスの《クラス指定
子》の右波括弧が現れた直後に定義が完了したとみなされる。このとき,そのメンバ関数は,定義されているとは限
らない。
クラス型の,完全オブジェクト 及び メンバ部分オブジェクトは,大きさがゼロであってはならない。
参考
クラスオブジェクトは,代入することができ,関数への引数として渡すことができ,関数によって返却
することができる。ただし ,複写に制限のあるクラスのオブジェクトは除く(
参照)
。等価性比較の
ような他の演算子は,利用者が定義して使うことができる(
#
参照)
。
構造体は,
《クラスキー》
を付けて定義するクラスとする。そのメンバ 及び 基底クラス(
)は,特に指
定がない限り公開(
)となる。共用体は,
《クラスキー》
を付けて定義するクラスとする。そのメンバは,特
に指定がない限り公開となり,一度に一つのデータメンバだけを保持する(
*#
参照)
。
参考
クラス型の集成体は,
#
で規定する。
"
互換構造体は,次のいずれももたない集成体クラスとする。
―
非
"
互換構造体( 又は その型の配列)である非静的データメンバ
―
非
"
互換共用体( 又は その型の配列)である非静的データメンバ
―
参照型である非静的データメンバ
―
利用者定義のコピー代入演算子
―
利用者定義のデストラクタ
同様に,
"
互換共用体は,次のいずれももたない集成共用体とする。
―
非
"
互換構造体( 又は その型の配列)である非静的データメンバ
―
非
"
互換共用体( 又は その型の配列)である非静的データメンバ
―
参照型である非静的データメンバ
―
利用者定義のコピー代入演算子
―
利用者定義のデストラクタ
"
互換クラスは,
"
互換構造体 又は
"
互換共用体のいずれかとする。
*
クラス名
クラス定義は,新しい型を導入する。
例
5
Q
&
R&
J
Q
&
R&
5
L&
J
+&
*&
上の例は,それぞれ異なる型をもつ三つの変数を宣言する。その宣言のもとでは,次のようになる。
L
%
+&
''
エラー
3
J
を
5
に代入
L
%
*&
''
エラー
3
を
5
に代入
これらの代入文の,型は合致していない。
5 &
J &
注
基底クラスの部分オブジェクトには,そのような制約はない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
上の二つの宣言は,多重定義関数(
)
の宣言であり,単に一つの関数
を
回宣言しているの
ではない。次の定義は,
F
を
回定義しているので,不適格となる。
F
Q
&
R&
F
Q
&
R&
''
エラー
3
二重定義
クラス定義は,それが定義された有効範囲内にクラス名を導入し ,それを囲んでいる有効範囲内にある,同じ名前
をもつ,クラス,オブジェクト,関数 などの他の宣言を隠ぺいする(
参照)
。同じ名前のオブジェクト,関数 及
び 列挙子がすでに宣言されている有効範囲内でクラス名が宣言された場合には,宣言が両方とも有効な範囲内では,
クラスは,
《詳述型指定子》
(
)によってだけ参照することができる。
例
Q
''
(((
R&
&
''
変数を定義するため
''
単なる
を使用。
! &
''
を関数として再宣言。
Q
!
&
''
構造体名
には,
''
接頭語
が必要。
''
(((
&
''
の呼出し
''
(((
R
単に
:
《クラスキー》
《識別子》
&;
で構成される宣言は,現在の有効範囲内の名前の再宣言 又は クラス名としての識
別子の事前宣言とする。これによって,クラス名が,現在の有効範囲に導入される。
例
Q
&
R&
Q
&
''
大域構造体
を
''
局所宣言で隠ぺいする。
!
&
''
局所構造体
への参照
Q
!
&
R&
''
局所構造体
の定義
&
''
影響のない再宣言
R
参考
このような宣言によって,クラスの定義の相互参照が可能となる。
例
H&
@
Q
''
(((
H
!@
0
H0 &
R&
H
Q
''
(((
H
!@
0
H0 &
R&
随伴宣言
は,
で規定する。演算子関数は,
#
で規定する。
《詳述型指定子》
(
)#
)は,宣言の一部に,
《型指定子》として使うこともできる。クラス宣言との違いは,詳
述名と同名のクラスが有効範囲内にあるならば ,詳述名がそのクラスを参照することとする。
例
Q
&
R&
Q
!
%
&
''
大域構造体
V
%
&
''
局所変数
R
参考
クラス名の宣言は,クラス定義 又は 《詳述型指定子》の中に《識別子》が現れた直後から有効となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6
!
6&
例えば ,上の宣言で,最初に指定された
6
はクラス名となり,その後,
6
クラスのオブジェクトへのポイ
ンタ名として再定義する。そのような振る舞いから,そのクラスを参照するために
6
による詳細宣
言を使わなくてはならない。そのような名前の技巧的な使い方は,紛らわしいことであり,推奨しない。
クラスを名前付ける《型定義名》
(
)
)は,
《クラス名》とするが,
《詳述型指定子》の中で使ってはならない(
)
参照)
。
*
クラスメンバ
メンバ指定
3
メンバ宣言
メンバ指定
アクセス指定子
3
メンバ指定
メンバ宣言
3
宣言指定子列
メンバ宣言子並び
&
関数定義
&
33
入れ子名前指定子
修飾なし識別子
&
!
宣言
テンプレート宣言
メンバ宣言子並び
3
メンバ宣言子
メンバ宣言子並び
,メンバ宣言子
メンバ宣言子
3
宣言子
純粋指定子
宣言子
定数初期化子
識別子
3
定数式
純粋指定子
3
%
.
定数初期化子
3
%
定数式
クラス定義中の《メンバ指定》は,クラスのメンバの全集合を宣言する。他のいかなる場所でもメンバを追加する
ことはできない。クラスのメンバは,次のものとする。
―
データメンバ
―
メンバ関数(
*
)
―
入れ子型
―
列挙子
データメンバ 及び メンバ関数は,静的 又は 非静的とする(
*
参照)
。入れ子型は,クラス中で定義したクラス(
*
及び
*)
参照),及び 列挙体(
)
),並びに 型定義宣言(
)
)を使ってメンバとして宣言してある任意の型とす
る。クラス中で定義した列挙体(
)
)中の列挙子は,そのクラスのメンバとする。
《メンバ宣言》は,それを随伴宣
言(
)に使う場合,及び 基底クラスのメンバの名前を派生クラス(
)
及び
参照)に導入するために使
う場合を除いて,クラスのメンバを宣言する。その各《メンバ宣言》は,そのクラスのメンバ名を一つ以上宣言しな
ければならない。同じ メンバを,
《メンバ指定》内で二度宣言してはならない。ただし ,入れ子クラス 又は メンバク
ラステンプレートは,それを宣言した後で定義することができる。
クラスは,
《クラス指定子》の右波括弧の直後で,完全定義されたオブジェクト型(
*
)
( 完全型とも呼ぶ。)とな
る。クラスの《メンバ指定》の範囲内で,そのクラスは,関数本体,省略時の実引数 及び コンストラクタの《コン
ストラクタ初期化子》
( 更に,入れ子クラス内のそれらを含む。)の中では完全型として扱う。クラス《メンバ指定》
内のそれらを除いた場所では,そのクラスは,不完全型として扱う。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
参考
単一の名前が,複数の関数メンバを指し示すことがあるが,それは,それらの型が十分に異なる場合と
する(
参照)
。
《メンバ宣言子》が《定数初期化子》をもつことができるのは,定値汎整数型 又は 定値列挙型の,静的メンバ(
*
)
を宣言する場合だけとする(
*
参照)
。
メンバは,コンストラクタを使って初期化することができる(
参照)
。
参考
コンストラクタなどの特殊メンバ関数は,
で規定する。
メンバは,
,
又は
としてはならない。
《宣言指定子列》は,コンストラクタ,デストラクタ 及び 変換関数の宣言には書かない。
《メンバ宣言子並び》は,
《クラス指定子》,
《列挙体指定子》 又は
:
《詳述型指定子》
;
という形式の《宣言指定子列》の後でだけ省略
することができる。純粋指定子は,仮想関数(
)の宣言でしか使ってはならない。
クラスオブジェクトとなる非静的メンバ(
*
)は,それ以前に定義したクラスのオブジェクトでなければならな
い。特に,クラス
中にクラス
のオブジェクトを含んではならない。しかし ,クラス
のオブジェクトへのポ
インタ 及び 参照を含むことはできる。配列を非静的メンバの型として使う場合には,すべての次元を指定しなけれ
ばならない。
次の場合を除き,クラスの非静的な,データメンバ 又は メンバ関数は,クラスメンバアクセスの構文規則(
##
)
によって参照しなければならない。
―
メンバへのポインタという形式で使う場合(
#
)
―
クラス 又は その派生クラスの非静的メンバ関数の本体の中で使う場合(
*
)
―
クラス 又は その派生クラスのコンストラクタのための《メンバ初期化子》の中で使う場合(
(
)
参考
非静的メンバ関数の型は,通常の関数型とし ,非静的データメンバの型は,通常のオブジェクト型とす
る。特殊なメンバ関数型 又は データメンバ型が存在するわけではない。
例
クラス定義の簡単な例
Q
S+.T&
&
!&
!&
R&
これは,
文字の配列,一つの整数 及び 同じ構造体への二つのポインタをもつ。この定義のもとで,次
の宣言は,
を
,
を
へのポインタと宣言する。
,
!&
この宣言によって,
V
は,
の指す構造体のメンバ
を参照し ,
(
は,構造体
の部
分木ポインタ
を参照し ,
(VS.T
は,
の部分木
のメンバ
の先頭文字を
参照する。
( 共用体ではない)クラスの非静的データメンバが《アクセス指定子》が間に入らずに宣言された場合,後で宣言
されたデータメンバのほうが,クラスオブジェクト内でより高位のアドレスになるように割り当てられる。
《アクセ
ス指定子》で分離された非静的メンバの割当て順序は,未規定とする(
)
。処理系によっては,境界調整の必要
性から,二つの連続するメンバの一方を他方の直後に割り付けないことも起こりうる。これは,仮想関数(
) 及
び 仮想基底クラス(
)を管理するための領域についても同じとする。
がクラス名である場合,次のそれぞれは,
と異なる名前をもたなければならない。
―
クラス
のすべての静的データメンバ
―
クラス
のすべてのメンバ関数
参考
この制約は,名前をもたないコンストラクタには適用されない(
参照)
。
―
それ自身が型であるような,クラス
のすべてのメンバ
―
列挙型であるような,クラス
のすべてのメンバのすべての列挙子
―
クラス
のメンバである無名共用体のすべてのメンバ
クラス
が利用者宣言のコンストラクタ(
)をもつ場合,クラス
のすべての非静的データメンバ は,
とは
異なる名前をもたなければならない。
二つの
"
互換構造体(
*
)の型が配置適合であるとは,非静的データメンバの個数が同じであって,対応する非静
的データメンバが(その順に )配置適合な型(
*
)をもつ場合とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
二つの
"
互換共用体(
*
)の型が配置適合であるとは,非静的データメンバの個数が同じであって,対応する非静
的データメンバが( 順序は問わず )配置適合な型(
*
)をもつ場合とする。
"
互換共用体が二つ以上の
"
互換構造体をもち,それらが同一の先頭メンバ並びを共有しており,かつ,
"
互換共
用体のオブジェクトがそれらの
"
互換構造体のいずれかを現在保持している場合,それらの
"
互換構造体のいずれで
あってもその同一の先頭メンバ並びを参照することができる。二つの
"
互換構造体が同一の先頭メンバ並びを共有す
るとは,対応するメンバが,一つ以上の先頭メンバの列に対して配置適合な型( 更に,ビットフィールド の場合,同
じ幅)をもっている場合とする。
"
互換構造体オブジェクトを指すポインタは,
を使って適切に変換することによって,先頭のメ
ンバを指すポインタとなる( 又は そのメンバがビットフィールド の場合,その格納単位を指す)
。また,逆も正しい。
参考
したがって,
"
互換構造体オブジェクト内に,適切に境界調整するために名前なしの詰め物が置かれる
ことがあるが,先頭に置かれることはない。
*
メンバ関数
クラス定義内で宣言する関数は,
3
指定子(
)付きで宣言する場合を除き,そのクラスの
メンバ関数と呼ぶ。メンバ関数は,
と宣言することができ,そのクラスの静的メンバ関数(
*
)となる。そ
う宣言しない場合,そのクラスの非静的メンバ関数(
*
及び
*
参照)となる。
メンバ関数は,クラス定義内で定義することができ(
),その場合,インラインのメンバ関数(
)
)となる。
また,メンバ関数が,すでにクラス定義内に宣言されているが,そのクラス定義内では定義されていない場合,その
メンバ関数をクラス定義の外で定義してもよい。クラス定義の外に現れるメンバ関数定義は,そのクラス定義を取り
囲む名前空間の有効範囲内になければならない。クラス定義の外に現れるメンバ関数定義の場合,並びに クラステン
プレートのメンバ関数 及び メンバ関数テンプレートの明示特化(
)
)の場合を除き,メンバ関数を再宣言しては
ならない。
インラインのメンバ関数は,
(静的 又は 非静的のいずれであっても)クラス定義の外で定義してもよい。ただし,そ
の場合,クラス定義内での宣言 又は クラス定義の外での定義のいずれかでその関数を
と宣言しなければな
らない。
参考
名前空間有効範囲内にあるクラスのメンバ関数は,外部結合をもつ。局所クラス(
*
)のメンバ関数
は,結合をもたない(
#
参照)
。
非インラインのメンバ関数の定義は,プログラム中に高々一つでなければならない。これに対する診断は不要とす
る。インラインのメンバ関数の定義は,プログラム中に複数存在してもよい(
及び
)
参照)
。
メンバ関数の定義が字句的にクラス定義の外にある場合,メンバ関数名は,演算子
33
を使ってクラス名で修飾し
なければならない。
参考
メンバ関数の定義で使われる名前( すなわち,省略時実引数を含む《仮引数宣言節》
(
(
)内,メン
バ関数本体内 又は コンストラクタ(
)の《メンバ初期化子》式(
(
)内にある名前)の検索は,
で規定する。
例
5
Q
&
&
&
R&
533
%
Q
R
ここで,クラス
5
のメンバ関数
は,大域的有効範囲内で定義されている。
533
という記法は,
が
5
のメンバであり,クラス
5
の有効範囲内にあることを示す。関数定義において,仮引数の型
は,クラス
5
内で宣言された型定義メンバ
を参照し,省略時実引数の
は,クラス
5
内で宣言された静的デー
タメンバ
を参照する。
メンバ関数内の静的局所変数は,メンバ関数がインラインか否かにかかわらず,常に同じオブジェクトを参照する。
メンバ関数は,そのクラスが定義された後で随伴宣言に現れてもよい。
局所クラスのメンバ関数は,インラインと定義するのであれば ,そのクラスの定義の中でインラインと定義しなけ
ればらない。
参考
メンバ関数は,関数型に対する型定義を使って宣言することができる(しかし ,定義はできない )。結
果のメンバ関数は,関数宣言子を明示的に書いた場合と,正確に同じ型をもつ(
#
参照)
。
&
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
F
Q
L&
''
L &
と同じ
+ &
*&
''
*
&
と同じ
R&
F33!
L
%
0F33L&
F33!
+
%
0F33+&
F33!
*
%
0F33*&
を参照。
*
非静的メンバ関数
非静的メンバ関数は,そのクラス型のオブジェクト 又は そのクラス型から派生したクラ
ス(
)のオブジェクトに対し,クラスメンバアクセス構文(
##
及び
参照)を使って呼び出してもよ
い。非静的メンバ関数は,関数呼出しの構文規則(
#
及び
参照)を使って,次のとおり直接呼び出して
もよい。
―
クラス 又は その派生クラスのメンバ関数の本体内からの呼出し,
―
クラス 又は その派生クラスのコンストラクタに対する《メンバ初期化子》
(
(
)からの呼出し
クラス
の非静的メンバ関数を,型
でも
から派生した型でもないオブジェクトに対して呼び出した場合,そ
の動作は未定義とする。
《識別子式》
(
#
)が,クラスメンバアクセス構文(
##
)の中になく,メンバへのポインタ(
#
)を作るた
めに使われていず,クラス
の非静的メンバ関数の本体の中 又は コンストラクタの《メンバ初期化子》の中で使わ
れており,かつ名前検索(
)によってこの《識別子式》の名前がクラス
又は
の基底クラスの非静的な非
型のメンバに対するものとして解決された場合,その《識別子式》は,
!
(
*
)を演算子
(
の左辺に置いた
《後置式》を使ったクラスメンバアクセス式に変形される。その結果,そのメンバ名は,呼び出す関数の対象となる
オブジェクトのメンバを参照することになる。同様に,名前検索中にクラス
のメンバ関数の定義に使われる《修飾
なし識別子》
(
#
)は,クラス
又は
の基底クラスの静的メンバ,列挙子 又は 入れ子型と解釈された場合,そ
の《修飾なし識別子》は,
《修飾付き識別子》に変形され,その中の入れ子名前指定子が メンバ関数のクラスを指し示
すことになる。
例
Q
S+.T&
&
!&
!&
!
!
!
&
R&
33!
!
!
Q
%
)
L&
$
%
Y
Y &
&
%
&
%
&
R
L
+
Q
L(YY 0+
. &
+(YY . .
&
R
メンバ関数
33
の本体では,メンバ名
,
,
及び
は,関数呼出し時のオ
ブジェクトのメンバを参照する。したがって,
L(YY 0
+ .
の呼出しでは,
は
L(
を参照し,
+(YY . .
の呼出しでは,
は
+(
を参照する。関数
,
及
び
は,クラス
のメンバ関数ではないので,別のところで宣言されていなければならない。
注
4
(
)も,例として参考になる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
非静的メンバ関数は,
,
又は
と宣言してもよい。これらの《
0
修飾子》は,
ポインタ(
*
)の型に影響を与える。これらは,メンバ関数の関数型(
#
)にも影響を与える。
と宣言さ
れたメンバ関数は定値メンバ関数とし,
と宣言されたメンバ関数は揮発性メンバ関数とし,
と宣言されたメンバ関数は定値揮発性メンバ関数とする。
例
5
Q
&
&
R&
ここで,
533
は定値メンバ関数,
533
は定値揮発性メンバ関数となる。
非静的メンバ関数は,仮想(
) 又は 純粋仮想(
)と宣言してもよい。
*
&
ポインタ
非静的メンバ関数(
*
)の本体内で,キーワード
は,左辺値でない式とし ,その値は,
関数の呼出し対象のオブジェクトのアドレスとする。クラス
のメンバ関数内で,
の型は,
!
とする。メン
バ関数が
と宣言されていれば
の型は
!
,メンバ関数が
と宣言されていれば
の型
は
!
,メンバ関数が
と宣言されていれば
の型は
!
とする。
定値メンバ関数内で,関数呼出し対象のオブジェクトは,
付きの場合のアクセス意味規則によってアクセス
される。したがって,
メンバ関数は,そのオブジェクト 及び その非静的データメンバを変更してはならない。
例
Q
&
&
Q
))&
R
Q
))&
R
''
エラー
R&
33
Q
&
R
33
の本体の中の
))
は,
33
の呼出し対象のオブジェクト(の一部)を変更しようとするので
不適格とする。このような変更は,
が
へのポインタ(つまり,
!
が定値の型)なので,定
値メンバ関数内では許されない。
同様に,揮発性メンバ関数では,そのオブジェクト 及び 非静的データメンバアクセスのとき,
付きの場
合のアクセス意味規則(
)#
)が適用される。
0
修飾されたメンバ関数が,オブジェクト式(
##
)から呼び出せるのは,オブジェクト式が,メンバ関数と同
じか,それより少なく
0
修飾されているときだけとする。
例
0
0
Q
( &
( &
( &
( &
''
エラー
R
は定値,
33
は定値でないメンバ関数となっている。
33
の
0
修飾のほうがオブジェクト式
より少ないので,
(
の呼出しは不適格となる。
コンストラクタ(
) 及び デストラクタ(
)は,
,
又は
と宣言しては
ならない。
参考
しかし ,これらの関数は,
0
修飾付きの型をもつオブジェクトを生成 又は 削除するために呼び出すこ
とができる(
及び
参照)
。
*
静的メンバ
クラスのデータメンバ 又は 関数メンバは,クラス定義中で
と宣言してもよい。その場合,
そのメンバは,そのクラスの静的メンバとなる。
クラス
の静的メンバ
&
は,
:
《修飾付き識別子》 式
33&;
で参照することができる。静的メンバを参照するに
は,必ずしもクラスメンバアクセス構文規則(
##
)を使わなくてもよい。静的メンバは,クラスメンバアクセス構
文規則を使って参照してもよい。その場合には,
《オブジェクト式》が評価される。
例
Q
3
&
R
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
0
&
Q
33
&
''
B>3
オブジェクト不要
( &
''
が呼び出される。
R
静的メンバは,そのクラス有効範囲内 又は そのクラスから派生したクラス(
)の有効範囲内では,直接参照して
もよい。その場合,その静的メンバの参照は,その現れたクラス有効範囲を《修飾付き識別子》の《入れ子名前指定
子》に指定した形の,
《修飾付き識別子》の式を使ったのと同じに扱う。
例
&
5
Q
&
R&
J
3
5
Q
&
R&
J33
%
&
''
J33 &
と同等
静的メンバの《宣言子識別子》に引き続く定義の中で《修飾なし識別子》
(
#
)が使われており,名前検索(
)
によってこの《修飾なし識別子》が,そのメンバのクラス( 又は そのメンバクラスの基底クラス)の静的メンバ,列
挙子 又は 入れ子型への参照であると分かった場合,その《修飾なし識別子》は,
《修飾付き識別子》の式に変形され
る。ここで,その式の中で《入れ子名前指定子》は,その静的メンバの含まれるクラス有効範囲を指す。静的メンバ
の定義では,そのクラス 又は その基底クラスの非静的メンバの名前を直接使ってはならない(
!J
演算子の演算対
象の場合も含む)。静的メンバの定義でこれらの非静的メンバを参照してもよいのは,メンバへのポインタ(
#
)
を作る場合 及び クラスメンバアクセス構文(
##
)を使う場合とする。
静的メンバは,通常のクラスメンバアクセス規則に従う(
参照)
。
!
指定子は,クラスメンバの宣言で使う
場合,クラス宣言内の《メンバ指定》の中に現れるメンバ宣言でしか使ってはならない。
参考
名前空間有効範囲に現れるメンバ宣言に
!
指定子を指定することはできない。
*
静的メンバ関数
参考
*
に示した規則は,静的メンバ関数にも適用される。
参考
静的メンバ関数は,ポインタ
(
*
)をもたない。
静的メンバ関数は,
としてはならない。同じ名前で同じ仮引数の型の静的メンバ関数 及び 非静的メンバ関
数の両者があってはならない(
参照)。静的メンバ関数は,
,
又は
と宣言し
てはならない。
*
静的データメンバ
静的データメンバは,クラスの部分オブジェクトの一部ではない。クラスのすべてのオブ
ジェクトで共有される静的データメンバは,ただ一つしかない。
クラス定義内の静的データメンバ宣言は,定義ではない。それは,
0
修飾付きの
ではない不完全型としても
よい。静的データメンバの定義は,そのメンバのクラス定義を囲む名前空間有効範囲内になければならない。名前空
間有効範囲における定義の中で,静的データメンバの名前は,演算子
33
を使ってクラス名で修飾しなければならな
い。静的データメンバの定義中の《初期化子》式は,そのクラスの有効範囲内にあるとする(
(
参照)
。
例
Q
!
P&
!
&
R&
!
33
%
P &
!
33P
%
&
クラス
の静的データメンバ
が大域的有効範囲で定義されている。
33
という記法が,
がクラス
のメンバであり,その有効範囲中にあ
ることを指定している。静的データメンバの定義中で,
《初期化子》式がクラス
の静的データメン
バ
を参照している。
参考
静的データメンバを定義すると,そのクラスのオブジェクトを生成するまでもなく,それは存在している。
例
上の例で,
及び
は,クラス
のオブジェクトをプログラムが生成
しなくても存在する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
静的データメンバが,
付き汎整数型 又は
付き列挙型の場合,クラス定義内の静的データ宣言には,
《定
数初期化子》を指定することができる。ここで,
《定数初期化子》は,汎整数定数式(
#*
)としなければならない。
その場合,そのメンバは,汎整数定数式中に,書くことができる。そのメンバは,それがプログラム内で使われると
き,やはり名前空間有効範囲内で定義しなければならないし ,名前空間有効範囲の定義の中に《初期化子》を含んで
はならない。
プログラム中で使う静的データメンバの定義は,ちょうど 一つでなければならない。処理系は,これに対する診断
は要求されない(
参照)
。無名クラス 及び 無名クラス内に直接的 又は 間接的に含まれるクラスは,静的データ
メンバを含んではならない。
参考
これは,そのような静的データメンバを定義するための機構がないからである。
名前空間有効範囲内のクラスの静的データメンバは,外部結合(
#
)をもつ。局所クラスは,静的データメンバ
をもってはならない。
静的データメンバは,非局所オブジェクトと同様に,初期化され,解体される(
(
及び
(
参照)
。
静的データメンバは,
(
)
)と指定してはならない。
*#
共用体
共用体では,どの時点をとっても,高々一つのデータメンバしか活性化できない。すなわち,ある時点
で共用体に格納できるのは,高々一つのメンバの値とする。
参考
共用体の使用を単純化するために,特別な保証が一つだけある。
"
互換共用体に二つ以上の
"
互換構造
体があり,それらが同一の先頭メンバ並び(
*
)を共有しており,かつその
"
互換共用体型のオブジェ
クトがこの
"
互換構造体のいずれかを現在保持しているならば ,ど の
"
互換構造体メンバでもその同一
の先頭メンバ並びを参照することが許される(
*
参照)
。
共用体の大きさは,その最大のデータメンバを保持するのに十分大きくなければならない。各データメンバは,それ
が構造体のただ一つのメンバであるかのように割り当てられる。共用体は,メンバ関数(コンストラクタ 及び デス
トラクタを含む。)をもつことができるが,仮想関数(
)はもってはならない。共用体は,基底クラスをもっては
ならない。共用体は,基底クラスとして使ってはならない。自明でない省略時コンストラクタ(
),自明でない
コピーコンストラクタ(
),自明でないデ ストラクタ(
),又は 自明でないコピー代入演算子(
#
及
び
参照)をもつクラスのオブジェクトは,共用体のメンバにはできない。更に,そのようなオブジェクトの配
列も不可とする。共用体に静的データメンバ 又は 参照型のメンバがあった場合,そのプログラムは不適格とする。
次の形式をもつ共用体を,無名共用体と呼ぶ。
メンバ指定
&
これは,無名の型の無名のオブジェクトを定義する。無名共用体の《メンバ指定》では,非静的データメンバしか定
義してはならない。
参考
入れ子型 及び 関数を,無名共用体内で宣言することはできない。
無名共用体のメンバ名は,無名共用体を宣言した有効範囲内の他のどの実体の名前とも異なっていなければならない。
名前検索においては,無名共用体の定義の後では,そのメンバは,無名共用体を宣言した有効範囲内で定義されたも
のとみなす。
例
Q
Q
&
!
&
R&
%
L&
''
(((
%
Y=Y&
''
(((
R
ここで,
及び
は,通常の( 非メンバの )変数のように使われるが,共用体のメンバなので,同じア
ドレスをもつ。
名前付き名前空間 又は 大域的名前空間で宣言する無名共用体は,
と宣言しなければならない。無名共用体
をブロック有効範囲で宣言する場合には,ブロック有効範囲の変数に指定ができる記憶域種別を付けるか 又は 記憶
域種別なしで宣言しなければならない。クラス有効範囲内の無名共用体の宣言には,記憶域種別を指定することはで
きない。無名共用体は,非公開メンバ 又は 限定公開メンバ(
)をもってはならない。無名共用体は,関数をもっ
てはならない。
オブジェクト 又は ポインタを宣言した共用体は,無名共用体ではない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
Q
&
!
&
R
,
!
%
0&
%
L&
''
エラー
V
%
L&
''
B>
単なる
への代入は不適格とする。共用体の外では,このメンバ名が見えないからである。たとえ見
えたとしても,どの特定のオブジェクトとも結び付けられない。
参考
利用者宣言コンストラクタのない共用体の初期化は,
#
で規定する。
*(
ビット フィールド
次の形式の《メンバ宣言子》によって,ビットフィールド を指定する。
識別子
3
定数式
ここで,コロンによって,ビットフィールド 名とその長さとが分離されている。ビットフィールド の属性は,クラス
メンバの型の一部ではない。
《定数式》は,
以上の汎整数定数式でなければならない。定数式は,ビットフィールド
の型のオブジェクト表現(
*
)のビット数より大きくてもよい。その場合,余計なビットは,詰め物ビットとして使
われ,ビットフィールド の値の表現(
*
)には使われない。クラスオブジェクト内のビットフィールド の割り当て方
は,処理系定義とする。ビットフィールド の境界調整は,処理系定義とする。ビットフィールドは,何らかのアドレ
ス取得可能な単位内に詰め込まれる。
参考
処理系によっては,ビットフィールド の割当て単位をまたがることもあるし ,またがないこともある。
右から左に割り当てる処理系もあるし ,左から右に割り当てる処理系もある。
《識別子》を省いたビットフィールド の宣言は,無名ビットフィールド の宣言とする。無名ビットフィールドは,メ
ンバにならず,初期化できない。
参考
無名ビットフィールド は,外部要因で決まった配置に合致させるための詰め物として有用である。
特殊なケースとして,幅ゼロの無名ビットフィールド は,次のビットフィールド の割当てを単位境界に調整する指定
となる。無名ビットフィールドを宣言するときだけ,
《定数式》に
を指定してもよい。
ビットフィールド は,静的メンバであってはならない。ビットフィールドは,汎整数型 又は 列挙型(
*
)でな
ければならない。単なる( 明示的に
も
も付かない)
,
,
又は
のビットフィー
ルドが符号付きか符号なしかは,処理系定義とする。
値は,ゼロでない大きさのビットフィールドにうまく格納
できる。アドレス演算子
0
を,ビットフィールドに使ってはならない。したがって,ビットフィールド へのポインタ
は存在しない。定値でない参照が,ビットフィールド に結合してはならない(
#
参照)
。
参考
型
0
の参照に対する初期化が,ビットフィールド を参照する左辺値である場合,その参照は,
このビットフィールド の値をもつように一時的に結合されるのであって,その参照がビットフィールドに
直接結合されることはない(
#
参照)
。
任意の大きさ(
ビットのビットフィールド の場合を含む)の真理値型のビットフィールドに,
又は
の
値を格納した場合,もとの真理値とビットフィールド 値は,一致しなければならない。列挙子の値を,同じ型の列挙
子のビットフィールド に格納し ,ビットフィールド のビット数がこの列挙型の値を保持するに十分な大きさをもつと
き,もとの列挙子の値とビットフィールド の値は,同じでなければならない。
例
"BB?
Q
%.
%L
R&
6
Q
"BB?
3L&
R&
6
&
Q
(
%
&
(
%%
''
これは真でなければならない
Q
'!
(((
!'
R
R
*)
入れ子クラスの宣言
クラスは,別のクラス内で定義することができる。別のクラス内で定義したクラスのこと
を,入れ子クラスと呼ぶ。入れ子クラスの名前は,それを囲むクラスにとって局所的とする。入れ子クラスの有効範
囲は,それを囲むクラスの有効範囲内とする。明示的なポインタ,参照 又は オブジェクト名を使う場合を除き,入
れ子クラス内の宣言では,それを囲むクラスの型名,静的メンバ 及び 列挙子だけを使用することができる。
例
&
&
Q
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
&
&
Q
Q
%
$ &
''
エラー
3
33
の参照になる。
%
&
''
エラー
3
33
の参照になる。
%
&
''
B>3
33
を参照
33
%
&
''
B>3
大域的な
を参照
%
&
''
B>3
大域的な
を参照
R
!
,
Q
V
%
&
''
B>3
33
への代入
R
R&
R&
!
%
.&
''
エラー
&
が有効範囲にない。
入れ子クラスの,メンバ関数 及び 静的データメンバは,そのクラスの定義を囲む名前空間有効範囲内に定義する
ことができる。
例
Q
3
Q
&
&
R&
R&
3333
%
L&
3333
Q
'!
(((
!'
R
クラス
が,名前空間有効範囲で定義されている場合,入れ子クラス
をクラス
内で宣言しておき,後でクラ
ス
の定義内で定義してもよいし ,クラス
の定義を囲む名前空間有効範囲内で後で定義してもよい。
例
8
Q
<L&
''
入れ子クラス前宣言
<+&
<L
QR&
''
入れ子クラスの定義
R&
833<+QR&
''
入れ子クラスの定義
メンバ関数と同様に,入れ子クラス内で定義された随伴関数(
)は,そのクラスの字句的な有効範囲内にある。
このことは,そのクラスの静的メンバ関数(
*
)としての名前結合の規則と同じ規則に従っており,かつ,それを囲
むクラスのメンバに対する特殊なアクセス権をもたない。
*
局所クラス宣言
クラスは,関数定義内で定義することができる。そのようなクラスを,局所クラスという。局
所クラスの名前は,それを囲む有効範囲内に局所的とする。局所クラスの有効範囲は,それを囲む有効範囲の中であ
り,関数外の名前が関数内の名前をアクセスするのと同じアクセス権とする。局所クラス内の宣言では,それを囲む
有効範囲からは,型名,静的変数,
付き変数,関数 及び 列挙子だけを使うことができる。
例
&
Q
&
&
&
Q
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
Q
&
R
''
エラー
3
は自動記憶域変数
Q
&
R
''
B>
Q
33&
R
''
B>
Q
&
R
''
B>
R&
''
(((
R
!
%
.&
''
エラー
3
は有効範囲にない。
取り囲む関数は,局所クラスのメンバへの特殊なアクセス権をもたない。これは,通常のアクセス規則に従う(
参照)
。局所クラスのメンバ関数は,それを定義する場合には,そのクラス定義内で定義しなければならない。
クラス
が局所クラスである場合,入れ子クラス
を
内で宣言しておき,後でクラス
の定義内で定義して
もよいし ,クラス
を定義した有効範囲内で後で定義してもよい。局所クラス内の入れ子クラスは,局所クラスと
する。
局所クラスは,静的データメンバをもってはならない。
**
入れ子型名
型名は,他の名前と正確に同じ有効範囲規則に従う。特に,クラス定義内で定義された型名は,修
飾がなければ ,そのクラスの外側で使うことはできない。
例
5
Q
3
<&
J
Q
'!
(((
!'
R&
<
&
R&
<
&
''
エラー
J
&
''
エラー
533J
&
''
B>
533<
&
''
B>
派生クラス
基底クラスの並びは,次の記法を使ってクラス定義内に指定できる。
基底節
3
3
基底指定子並び
基底指定子並び
3
基底指定子
基底指定子並び
基底指定子
基底指定子
3
33
入れ子名前指定子
クラス名
アクセス指定子
33
入れ子名前指定子
クラス名
アクセス指定子
33
入れ子名前指定子
クラス名
アクセス指定子
3
《基底指定子》の中の《クラス名》は,不完全定義クラスであってはならない(
*
参照)。このクラスのことを,
宣言しようとするクラスに対する直接基底クラスと呼ぶ。基底クラス名の名前検索中には,非型の名前は無視される
(
)
参照)。見つかった名前が《クラス名》でない場合,プログラムは不適格とする。クラス
がクラス
の基
底クラスとなるのは,
が
の直接基底クラスであるか,
が
の基底クラスのうちのいずれかの直接基底クラス
である場合とする。あるクラスが,基底クラスであるが,直接基底クラスではない場合,それは間接基底クラスと呼
ぶ。クラスは,その( 直接 又は 間接の)基底クラスから( 直接 又は 間接に )派生したという。
参考
《アクセス指定子》の意味は
で規定する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
基底クラスのメンバは,派生クラスにおいて再定義されない限り,派生クラスのメンバでもある。基底クラスのメンバ
は,派生クラスに継承されるという。継承されたメンバは,その名前が隠ぺいされているか,あいまいな場合(
)
を除き,派生クラスの他のメンバと同様に,式で参照することができる。
参考
間接 又は 直接の基底メンバを明示的に参照するために,有効範囲解決演算子
33
(
#
)を使うことが
できる。これによって,派生クラス内で再定義した名前をアクセスすることができる。派生クラス自体が,
アクセス制御に当って基底クラスとして作用することもある(
参照)。派生クラスへのポインタは,
アクセス可能な基底クラスへのポインタに,あいまい性なく暗黙に変換することができる(
参照)。
派生クラスの型の左辺値は,アクセス可能な基底クラスへの参照にあいまい性なく結合することができる
(
#
参照)
。
《基底指定子並び》は,派生クラスの型に含まれる基底クラス部分オブジェクトの型を指定する。
例
"
Q
3
&
R&
#
3
"
Q
3
&
R&
#+
3
#
Q
3
&
R&
ここで,クラス
#+
のオブジェクトは,クラス
#
を部分オブジェクトとしてもつ一方,ク
ラス
#
は,クラス
"
を部分オブジェクトとしてもつ。
基底クラスの部分オブジェクトが最派生オブジェクト(
)の中で割り当てられる順序は,規定しない。
参考
派生クラス 及び その基底クラスの部分オブジェクトは,有向非循環グラフ
33
1
*
&
K
によって表現できる。ここで,矢印は,
:
どこそこから直接派生した
;
という意味とする。部分オブ
ジェクトの
*
&
K
は
:
部分オブジェクト束
;
と呼ぶことが多い。
"
↑
#
↑
#+
矢印は,メモリ上の物理表現ではない。
参考
基底クラスを表すオブジェクトの初期化は,コンストラクタの中で指定することができる(
(
参照)
。
参考
基底クラスの部分オブジェクトの配置(
)
)は,同じ型の最派生オブジェクトの配置とは異なってもよ
い。基底クラスの部分オブジェクトの多相的な動作(
)
)は,同じ型の最派生オブジェクトとは異なっ
てもよい。基底クラスの部分オブジェクトの大きさは,ゼロであってもよい(
*
)が,同一の型の二つの
部分オブジェクトが,同じ最派生オブジェクトに入っている場合,それらを,同じアドレスに割り当てて
はならない(
#
参照)
。
多重基底クラス
クラスは,任意の個数の基底クラスから派生することができる。
参考
複数の直接基底クラスを使う場合,多重継承と呼ばれる。
例
6
Q
'!
(((
!'
R&
"
Q
'!
(((
!'
R&
7
Q
'!
(((
!'
R&
#
3
6
"
7
Q
'!
(((
!'
R&
参考
コンストラクタ(
(
),後始末(
) 及び 記憶域配置(
*
及び
参照)による初期化の意
味規則によって指定される場合を除き,派生の順序は,意味をもたない。
派生クラスの直接基底クラスとして,一つのクラスを複数回指定してはならない。
参考
一つのクラスを,間接基底クラスとしてならば 複数回指定することができ,直接基底クラスであって,
かつ間接基底クラスであってもよい。そのようなクラスでは,制限が生じる。直接基底クラスの非静的な
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
データメンバ 及び 関数メンバは,派生クラスの有効範囲内で参照することができない。しかし ,静的メ
ンバ,列挙体 及び 型は,あいまい性なく参照することができる。
例
5
Q
'!(((!'
R&
J
3
5
5
Q
'!
(((
!'
R&
''
不適格
?
Q
3
&
'!
(((
!'
R&
6
3
?
Q
'!
(((
!'
R&
"
3
?
Q
'!
(((
!'
R&
7
3
6
"
Q
&
'!
(((
!'
R&
''
適格
#
3
6
?
Q
&
'!
(((
!'
R&
''
適格
基底クラスは,基底クラス指定子にキーワード
と指定した場合,仮想とし,指定しなかった場合,非仮想
とする。最派生のオブジェクト(
)は,そのクラス束において非仮想基底クラスが現れるごとに,その基底クラス
の部分オブジェクトをもつ。最派生のオブジェクトは,そのクラス束において仮想基底クラスが複数現れても,その
基底クラスの部分オブジェクトを一つだけもつ。
例
上の例のクラス型
7
の場合,型
7
のオブジェクト内に,
( 非仮想)基底クラス
?
の出現ごとに別々の部分オ
ブジェクト
?
をもつ。クラス
7
を上のように定義した場合,クラス
7
のオブジェクトは,次のとおりクラ
ス
?
の部分オブジェクトを二つもつ。
8
8
&
4
"
このような束では,ど の部分オブジェクトかを示すために明示的修飾を使うことができる。関数
733
の本体では,次のようにして,
?
のそれぞれの部分オブジェクトのメンバ
を参照することができる。
733
Q
633
%
"33&
R
''
適格
ここで,
633
又は
"33
という修飾がないと,
733
の定義は,あいまい(
)となるので,不適格と
なる。
もう一つの例を示す。
例
H
Q
'!
(((
!'
R&
6
3
H
Q
'!
(((
!'
R&
"
3
H
Q
'!
(((
!'
R&
7
3
6
"
Q
'!
(((
!'
R&
クラス型
7
のオブジェクト
に対し,型
H
の仮想基底クラスをもつと宣言した
のそれぞれの基底部分
オブジェクトは,型
H
の一つの部分オブジェクトを共有する。上で宣言されたクラス
7
では,型
7
のオブ
ジェクトは,下記に示すように,クラス
H
の部分オブジェクトを一つしかもたない。
$
&
4
"
クラスは,与えられた型の仮想基底クラス 及び 非仮想基底クラスの両方をもつことができる。
例
"
Q
'!
(((
!'
R&
5
3
"
Q
'!
(((
!'
R&
J
3
"
Q
'!
(((
!'
R&
K
3
"
Q
'!
(((
!'
R&
66
3
5
J
K
Q
'!
(((
!'
R&
クラス
66
のオブジェクトに対して,
66
のクラス束における基底クラス
"
のすべての
の出現
は,型
66
のオブジェクト内で唯一の
"
の部分オブジェクトに対応する。そして,型
66
のクラス束におけ
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
る基底クラス
"
のすべての( 非仮想の)出現は,型
66
のオブジェクト内でそれぞれ異なる
"
の部分オブ
ジェクトに一対一に対応する。上の例で,クラス
66
は,クラス
"
の部分オブジェクトを二つもつ。すな
わち,次に示すとおり,
K
の
"
,並びに
5
及び
J
が共有する仮想の
"
の二つをもつ。
4
4
6
L
M
&&
メンバ名の検索
メンバ名の検索によって,クラス有効範囲(
(
)内での名前(《識別子式》)の意味が決
まる。名前検索の結果があいまいな場合,プログラムは不適格とする。
《識別子式》に対して,名前検索は,
の
クラス有効範囲から始まる。
《修飾付き識別子》については,名前検索は,
《入れ子名前指定子》の有効範囲から始ま
る。名前検索は,アクセス制御の前に行われる(
及び
参照)
。
次の順序に従って,クラス有効範囲
7
での名前検索の結果が決まる。最初に,そのクラス 及び その基底クラスのそ
れぞれにおいて,その名前の宣言が検索される。部分オブジェクト
6
が部分オブジェクト
"
の基底クラスの部分オブ
ジェクトである場合,部分オブジェクト
6
中のメンバ名
は,部分オブジェクト
"
のメンバ名
によって隠ぺいされ
る。このように隠ぺいされた宣言は,検索対象としない。
《
!
宣言》で導入された宣言のそれぞれは,その《
!
宣言》で指定した宣言を含む型
7
の部分オブジェクトからのものとして検索する
。検索結果の宣言集合の宣言が
すべて同じ型の部分オブジェクトに由来するものとはならなかった場合,又は 検索結果の宣言集合が非静的メンバを
もち,別々の部分オブジェクトに由来する複数のメンバを含んでいる場合,検索にあいまい性があり,そのプログラ
ムは不適格となる。あいまいでない場合,この集合が名前検索の結果となる。
例
6
Q
3
&
! &
&
&
&
R&
"
Q
&
&
3
&
&
&
&
R&
7
3
6
"
Q
R&
7!
Q
V
%
L&
''
エラー
3
633
か
"33
かあいまい
V &
''
エラー
3
633
か
"33
かあいまい
V &
''
エラー
3
633
か
"33
かあいまい
VL &
''
エラー
3
633
か
"33
かあいまい
V &
''
エラー
3
633
か
"33
かあいまい
V
%
L&
''
エラー
3
633
か
"33
かあいまい
V &
''
B>
VL &
''
B>
R
例
G
Q
&
R&
H
3
G
Q
R&
注
《
宣言》は,継承されたメンバのあいまい性を解決するのに使われない(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
I
3
G
Q
G33&
R&
5
3
H
I
Q
&
R&
533
Q
&
''
G33
は,
I33
と
H
中の
G33
の
+
箇所で
''
見つかるが,
G33
が
なのであいまいでない。
R
多重定義関数の名前が,あいまい性なく見つかった場合,アクセス制御の前に,多重定義解決(
)が行われる。
あいまい性は,クラス名で修飾することによって解決されることが多い。
例
6
Q
3
&
R&
"
Q
3
&
R&
7
3
6
"
Q
Q
633
)
"33 &
R
R&
基底クラス
において定義されている静的メンバ,入れ子型 又は 列挙子は,型
の基底クラスの部分オブジェク
トを複数個含んでいる場合であっても,あいまい性なく見つけられる。二つの基底クラスの部分オブジェクトは,そ
れらに共通する仮想基底クラスの非静的メンバを共有する。
例
H
Q
3
&
R
&
6
Q
3
&
&
Q
R&
R&
"
3
6
H
QR&
7
3
6
H
QR&
#
3
"
7
QR&
#!
Q
V))&
''
B>3
は一つ
V))&
''
B>3
は一つ
%
V&
''
B>3
は一つ
列挙子
V))&
''
エラー
3
#
内に
が二つあるのであいまい
R
仮想基底クラスが使われているとき,隠ぺいしている宣言を介さない部分オブジェクト束を通って隠ぺいされた宣
言に到達できる場合もある。これは,あいまいではない。非仮想基底クラスを同様に使った場合は,あいまいとする。
この場合,他をすべて隠ぺいする一意な名前の実体が存在しない。
例
H
Q
3
&
&
R&
I
Q
3
&
&
R&
"
3
H
I
Q
3
&
&
&
&
R&
7
3
H
I
Q
R&
#
3
"
7
Q
&
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
C
$
C
4
"
*
H
で定義された名前 及び 左側の
I
で定義された名前は,
"
で隠ぺいされているが,右側の
I
で定義され
た名前は,全く隠ぺいされない。
#33
Q
))&
''
B>3
"33
が,
H33
を隠ぺいしている。
&
''
B>3
"33
が,
H33
を隠ぺいしている。
))&
''
エラー
3
"33
及び
7
の
I33
がある。
&
''
エラー
3
"33
及び
7
の
I33
がある。
R
派生クラスのポインタ 又は 左辺値からそのいずれかの基底クラスのポインタ 又は 参照への明示的 又は 暗黙的な
変換は,その基底クラスを表す一意なオブジェクトをあいまい性なく参照していなければならない。
例
H
Q
R&
6
Q
R&
"
3
6
H
Q
R&
7
3
6
H
Q
R&
#
3
"
7
Q
R&
Q
#
&
"!
%
0&
6!
%
0&
''
エラー
3
7
の
6
か
"
の
6
かあいまいである。
H!
%
0&
''
B>3
部分オブジェクト
H
は,一つだけである。
R
仮想関数
仮想関数によって,動的結合 及び オブジェクト指向プログラミングが可能になる。仮想関数を宣
言したり継承したりするクラスのことを,多相的クラスと呼ぶ。
クラス
&
で仮想メンバ関数
'
が宣言されており,
&
から直接 又は 間接に派生したクラス
(
"
)
で,
&33
'
と同じ名前 及び 仮引数並びをもつメンバ関数
'
が宣言されている場合,
(
"
)33
'
は,
(
と
宣言されていなくても)仮想となり,
&33
'
を上書きする
。簡便性のため,すべての仮想関数は,自分自身
を上書きするものとする。適格なクラスでは,そのクラス 又は そのすべての直接 又は 間接の基底クラスで宣言され
た仮想関数のそれぞれについて,その関数自身 及び その他のすべての上書き関数を上書きする最終上書き関数が一
意に存在する。メンバ検索規則(
)によって,派生クラス有効範囲における仮想関数の最終上書き関数が決定さ
れるが,
《
!
宣言》で導入される名前は,無視される。
例
6
Q
&
R&
"
3
6
Q
&
R&
7
3
"
6
Q
633&
R&
Q
7
&
( &
''
最終上書き関数
"33
を呼び出す。
(733 &
''
宣言があるため
633
を呼び出す。
R
注
ある関数が,ある仮想関数と同じ名前であるが,異なる仮引数並びをもつ場合(
),必ずしも仮想ではないし ,上書きしない。上書
きする関数の宣言中に
#
指定子を書くことは,適格であるが冗長となる( 意味をもたない)
。アクセス制御(
)は,上書きの決
定に影響しない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
参考
仮想メンバ関数が上書きされるためには,それが可視である必要はない。
例
"
Q
&
R&
#
3
"
Q
&
R&
#+
3
#
Q
&
R&
クラス
#
の関数
が,基底クラス
"
の仮想関数
を隠ぺいする。
#33
は,仮想関数ではな
い。しかし ,クラス
#+
の
は,
"33
と同じ名前で同じ仮引数並びなので仮想関数となり,
"33
を上書きする。
"33
は,クラス
#+
からは見えないが,上書きされる。
デストラクタは継承されないが,仮想であると宣言された基底クラスのデストラクタは,派生クラスのデストラク
タによって上書きされる(
及び
#
参照)
。
上書きする関数の返却値の型は,上書きされる関数の返却値の型と同一であるか,又は 二つの関数のクラスで共変
的であるかのいずれかでなければならない。ここで,関数
33'
が関数
33'
を上書きしている場合,次の条件がす
べて成り立つときに,両方の関数の返却値の型は,共変的であるという。
―
返却値の型が,ともにクラスへのポインタ 又は クラスへの参照である。
―
33'
の返却値の型のクラスが
33'
の返却値の型のクラスと同じであるか,又は それが
33'
の返却値
の型のクラスの,あいまい性がなくてアクセス可能な,直接 若しくは 間接の基底クラスとなっている。
―
ポインタ 又は 参照が同一の
0
修飾をもち,
33'
の返却値のクラス型の
0
修飾が,
33'
の返却値の
クラス型の
0
修飾より多くない。
33'
の返却値の型が
33'
の返却値の型と異なる場合,
33'
の返却値のクラス型は,
33'
の宣言の位置で完全で
あるか 又は クラス型
そのものでなければならない。上書きする関数が上書きされる関数の最終上書き関数として
呼び出されたとき,その結果は,上書きされた( 静的に選択された )関数の返却値の型に変換される(
#
参照)
。
例
"
QR
#
3
"
Q
#&
R&
"
Q
L &
+ &
* &
"!
M &
"!
/ &
&
R&
AP
3
"
Q
#!
M &
''
エラー
3
"#
の基底クラス
をアクセスできない。
R&
6&
#
3
"
Q
L &
''
仮想であり
"33L
を上書きする。
+ &
''
仮想でない。
"33+
を隠ぺいする。
* &
''
エラー
3
返却値の型だけが異なっている。
#!
M &
''
B>3
派生クラスへのポインタを返す。
6!
/ &
''
エラー
3
返却値が不完全クラスを指す。
H
&
R&
Q
#
&
"!
%
0&
''
#!
から
"!
への標準変換。
VL &
''
#33L
を呼び出す。
V+ &
''
"33+
を呼び出す。
注
クラスへの多レベルポインタ 又は クラスへの多レベルポインタへの参照は,許されない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
V &
''
仮想でない
"33
を呼び出す。
"!
%
VM &
''
#33
を呼び出し,返却値を
"!
に変換する。
#!
%
0&
#!
%
VM &
''
#33
を呼び出す。返却値の
"!
への変換なし 。
V+ &
''
不適格
3
実引数の不一致。
R
参考
仮想関数の呼出しの解釈は,呼出し対象のオブジェクトの型に依存する( 動的な型)が,仮想でない関
数の呼出しの解釈は,呼出し対象のオブジェクトへのポインタ 又は 参照の型だけに依存する( 静的な型)
(
#
参照)
。
参考
0
指定子は暗黙にメンバ性を与えるので,仮想関数は,非メンバ(
)
)関数にはならない。更に
仮想関数の呼出しは特定のオブジェクトに依存してどの関数を呼び出すかが決まるので,仮想関数は,静
的メンバにはならない。あるクラスで宣言した仮想関数を別のクラスで
と宣言することができる。
クラス内で宣言した仮想関数は,そのクラス内で定義するか,純粋宣言するか,又は その両方ともするかしなけれ
ばならない(
参照)
。しかし ,診断メッセージは不要とする(
参照)
。
例
複数の基底クラスをもつ仮想関数の使用例を次に示す。
6
Q
&
R&
"L
3
6
Q
''
非仮想の派生である。
&
R&
"+
3
6
Q
&
R&
#
3
"L
"+
Q
''
#
は,
6
の部分オブジェクトを二つもつ。
R&
Q
#
&
''
6!
%
0&
''
これは,あいまいなので不適格になる。
"L!
L
%
0&
6!
%
L&
#!
%
0&
V &
''
#33"L33
を呼び出す。
V &
''
不適格
3
あいまい
R
上例の
#
では,クラス
6
が二つ存在しており,したがって仮想関数
633
も二つ存在する。
"L33633
の最
終上書き関数は
"L33
であり,
"+33633
の最終上書き関数は
"+33
となる。
次の例は,一意な最終上書き関数をもたない関数を示す。
6
Q
&
R&
H"L
3
6
Q
''
仮想派生であることに注意
&
R&
H"+
3
6
Q
&
R&
8
3
H"L
H"+
Q
''
不適格
R&
B
3
H"L
H"+
Q
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
&
R&
H"L33
と
H"+33
の両方が
633
を上書きするが,クラス
8
内に,この両者の上書き関数がない。し
たがって,この例は不適格となる。しかし ,クラス
B
は,
B33
が最終上書き関数となるので適格
となる。
次の例では,上例の適格なクラスを使っている。
H"L
3
6
Q
''
を宣言しない。
R&
#
3
H"L
H"+
Q
R&
Q
H"L!
L
%
#&
LV &
''
H"+33
を呼び出す。
R
有効範囲演算子(
#
)を用いた明示的修飾によって,仮想関数の呼出しを抑止する。
例
"
Q
3
&
R&
#
3
"
Q
3
&R&
#33
Q
'!
(((
!'
"33 &
R
ここで,
#33
内の関数呼出しは,事実
"33
となり,
#33
とならない。
抽象クラス
抽象クラスという機構によって汎用的な記法が提供される。例えば ,
という汎用的な名前
によって,具体的な
や
という変異形を実際に使えるようにできる。抽象クラスは,派生クラスが各
種の処理系に提供するインタフェースを定義するためにも使うことができる。
抽象クラスは,他のクラスの基底クラスとしてしか書くことができないクラスとする。抽象クラスのオブジェクト
は,派生クラスの部分オブジェクトとして生成される場合を除き,生成することができない。クラスは,少なくとも
一つの純粋仮想関数をもつとき,抽象クラスとなる。
参考
このような関数は,継承されることがある( 下記参照)
。
仮想関数は,クラス宣言中の関数宣言において,
《純粋指定子》
(
*
)をつけることによって純粋と指定される。純粋
仮想関数は,
《修飾付き識別子》の構文規則を使って明示的に呼び出す場合に限り,定義する必要がある(
#
参照)
。
例
Q
'!
(((
!'
R&
Q
''
抽象クラス
&
''
(((
3
Q
&
R
Q
%&
&
R
%
.&
''
純粋仮想
%
.&
''
純粋仮想
''
(((
R&
参考
一つの関数宣言によって,
《純粋指定子》 及び 定義の両方を指定することはできない。
例
7
Q
%
.
Q
R&
''
不適格
R&
抽象クラスは,仮引数型,関数返却値の型 及び 明示変換の型として使ってはならない。抽象クラスへのポインタ
及び 参照を,宣言することができる。
例
&
''
エラー
3
抽象クラスのオブジェクト
!
&
''
B>
&
''
エラー
&
''
エラー
0
0 &
''
B>
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
あるクラスが,純粋仮想の最終上書き関数が最終上書きする純粋仮想関数を一つ以上もっているか 又は 継承して
いる場合,そのクラスは,抽象クラスとする。
例
P
3
Q
&
3
Q
R
''
P33
は,純粋仮想とする。
R&
33
が純粋仮想なので,
33
も省略時規定から純粋仮想となる。これに対
して別の例を示す。
3
Q
&
3
Q
R
&
''
定義がどこかで必要である。
R&
この宣言によって,
は,抽象クラスではなくなり,
33
の定義が必要になる。
参考
抽象クラスが,抽象クラスでないクラスから派生することがあり,純粋仮想関数が純粋でない仮想関数
を上書きすることもある。
抽象クラスのコンストラクタ(又は デストラクタ)からメンバ関数を呼び出すことができる。このようなコンスト
ラクタ( 又は デストラクタ)から構築( 又は 解体)されるオブジェクトに対して,直接 又は 間接に純粋仮想関数の
仮想呼出し(
)を行ったとき,その効果は未定義とする。
メンバアクセス制御
クラスのメンバは,次のいずれかとする。
―
非公開(
)この種別のクラスメンバの名前は,それが宣言されているクラスの,メンバ,随伴関
数 及び 随伴クラスだけが使うことができる。
―
限定公開(
)この種別のクラスメンバの名前は,それが宣言されているクラスの,メンバ,随
伴関数 及び 随伴クラス,並びに このクラスの派生クラスの,メンバ,随伴関数 及び 随伴クラスだけが
使うことができる(
#
参照)
。
―
公開(
)この種別のクラスメンバの名前は,アクセス制限なしにどこででも使うことができる。
キーワード
で定義されたクラスのメンバは,特に指定がない限り非公開とする。キーワード
又は
で定義されたクラスのメンバは,特に指定がない限り公開とする。
例
5
Q
&
''
533
は指定がないので非公開
R&
FQ
&
''
F33
は指定がないので公開
R&
アクセス制御に関する規定は,名前に対して一様に適用する。これは,名前の参照が現れた場所が宣言中であるか
式中であるかによらない。
参考
アクセス制御は,随伴宣言(
) 及び 《
!
宣言》
(
)
)の中に書かれた名前にも適用される。
多重定義関数の名前に対しては,アクセス制御は,多重定義解決によって選択された関数にだけ適用する。
参考
アクセス制御は,名前に対して適用されるので,アクセス制御を型定義名に適用したときには,型定義
名自体のアクセスの可否だけが考慮される。型定義によって参照される実体へのアクセスの可否は,考慮
されない。
例
6
Q
"
Q
R&
3
"
""&
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
Q
633""
&
''
B>
,型定義名
633""
は公開
633"
&
''
アクセス誤り,
633"
は非公開
R
制御されるのは,メンバ 及び 基底クラスへのアクセスであって,可視性ではない。メンバ 及び 基底クラスがアク
セス不可であっても,メンバの名前は依然として可視であり,基底クラスへの暗黙の型変換がなおも考慮される。構
文要素の解釈は,アクセス権に関係なく行われる。確定した解釈が,アクセス不可なメンバ名 又は 基底クラスを使
うことになるとき,その構文要素は,不適格とする。
で定めるすべてのアクセス制御が,それぞれの有効範囲からのクラスメンバ名へのアクセスの可否を左右する。
クラスメンバの定義がそのメンバの属するクラス定義の外に現れている場合,その定義中で使われる名前のアクセス
制御は,すべてのメンバ定義がその メンバの属するクラスの有効範囲内に現れていた場合と同様にして扱う。特に,
関数返却値の型の一部としてアクセスされたメンバ名にも,他と同様にアクセス制御を適用する。ただし ,その使用
でのアクセス能力は,関数宣言子の残りの部分を構文解析しないと決められない。同様に,静的データメンバを構築
又は 解体するために呼び出されるコンストラクタ,変換関数 又は デストラクタの暗黙の呼出しに対するアクセス制
御は,これらの呼出しがそのメンバの属するクラスの有効範囲にあるとして扱う。
例
6
Q
<&
''
非公開メンバ
<
&
<
< &
<
&
R&
633<
633
Q
.&
R
633<
633<
%
633 &
633<
633<
Q
.&
R
633<
633
%
.&
ここで,
633
及び
633
はクラス
6
のメンバであり,
はクラス
6
の随伴なので,
633<
の使用はすべ
て適格となる。このとき,例えば
633<
の最初の使用でのアクセスの検査は,
633<
がクラス
6
のメンバの
返却値の型として使われていると判定がつくまで,遅延させられることになる。
入れ子クラスのメンバの定義がその入れ子クラスの定義の外側に現れている場合,そのメンバの名前は,そのメン
バの属するクラスを取り囲むクラスの名前で修飾してもよい。このとき,それらの名前がそれぞれを取り囲むクラス
の非公開のメンバであってもよい。
例
#Q
8Q
&
R&
R&
#33833
%
L&
''
B>3
8
は非公開であるがアクセス誤りにならない。
省略時実引数式(
(
)内の名前は,宣言時に結合され,そのアクセスもその時点に検査される。省略時実引数式
のそれぞれの使用時にアクセスが検査されるわけではない。関数テンプレート 及び クラステンプレート内の省略時
実引数に対するアクセスの検査は,
)
で規定する。
アクセス指定子
メンバ宣言は,
《アクセス指定子》
(
)によってラベル付けすることができる。
アクセス指定子
3
メンバ指定
《アクセス指定子》は,クラス定義の終端に達するか,次のアクセス指定子が現れるかするまでの,それに続くメン
バに対するアクセスの規則を指定する。
例
5
Q
&
''
533
は
の場合の省略時規定によって非公開
3
&
''
533
は公開
&
''
533
は公開
R&
アクセス指定子は,何個あってもよく,その順序について特別の要求もない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
F
Q
&
''
F33
は
の場合の省略時規定によって公開。
3
&
''
F33
は限定公開
3
&
''
F33
は非公開
3
&
''
F33
は公開
R&
《アクセス指定子》ラベルで分離されたデータメンバ相互の割付け順序は,規定しない(
*
参照)
。
クラス定義内でメンバが再宣言される場合,再宣言でのアクセスの指定は,元の宣言と同じでなければならない。
例
F
Q
6&
3
6Q
R&
''
誤り
3
アクセスの種別は変更できない。
R&
基底クラス 及び 基底クラスメンバのアクセスの可否
あるクラスが他のクラスの基底クラス(
)としてア
クセス指定子
を使って宣言されているとき,基底クラスの公開メンバ 及び 限定公開メンバは,派生クラス
の公開メンバ 及び 限定公開メンバとして,それぞれアクセス可能となる。あるクラスが他のクラスの基底クラスと
してアクセス指定子
を使って宣言されているとき,基底クラスの公開メンバ 及び 限定公開メンバは,派
生クラスの限定公開メンバとしてアクセス可能とする。あるクラスが他のクラスの基底クラスとしてアクセス指定子
を使って宣言されているとき,基底クラスの公開メンバ 及び 限定公開メンバは,派生クラスの非公開メン
バとしてアクセス可能とする。
基底クラスに《アクセス指定子》が書いてない場合,派生クラスを
と宣言してあれば
を想定し ,
と宣言してあれば
を想定する。
例
"
Q
'!
(((
!'
R&
#L
3
"
Q
'!
(((
!'
R&
#+
3
"
Q
'!
(((
!'
R&
#*
3
"
Q
'!
(((
!'
R&
''
"
は省略時規定で非公開
#M
3
"
Q
'!
(((
!'
R&
#/
3
"
Q
'!
(((
!'
R&
#-
3
"
Q
'!
(((
!'
R&
''
"
は省略時規定で公開
#,
3
"
Q
'!
(((
!'
R&
#N
3
"
Q
'!
(((
!'
R&
ここで
"
は,
#+
,
#M
及び
#-
の公開基底,
#L
,
#*
及び
#/
の非公開基底,並びに
#,
及び
#N
の限定公
開基底となる。
参考
非公開基底クラスのメンバは,継承メンバ名としてはアクセスできなくても直接にアクセスできること
がある。ポインタ変換(
) 及び 明示キャスト(
#
)の規定によると,派生クラスへのポインタから
アクセス不可能な基底クラスへのポインタへの変換は,暗黙の型変換を使ったのでは不適格となり,明示
キャストを使うと適格となることがある。
例
"
Q
3
&
''
非静的メンバ
&
''
静的メンバ
R&
#
3
"
Q
R&
##
3
#
Q
&
R&
##33
Q
%
*&
''
エラー
3
は
#
で非公開
%
*&
''
エラー
3
は
#
で非公開
注
で規定したとおり,基底クラスの非公開メンバは,基底クラス宣言中の随伴宣言によって明示的にアクセスを認めない限り,派生
クラスであってもそこからアクセスできない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
33"
&
(
%
*&
''
B>3
(
は
V
と違う。
(
%
*&
''
B>3
(
は
V
と違う。
33"33
%
*&
''
B>
33"!
L
%
&
''
エラー
3
"
は非公開基底クラス
33"!
+
%
33"! &
''
B>3
キャストして
+V
%
*&
''
B>3
"
へのポインタを介したアクセス
R
基底クラスは,そこで導入した公開メンバがアクセス可能なとき,アクセス可能という。基底クラスがアクセス可
能ならば ,派生クラスへのポインタをその基底クラスへのポインタに暗黙に変換することができる(
及び
参照)
。
参考
したがって,クラス
のメンバ,随伴クラス 及び 随伴関数は,
を,
の非公開 又は 限定公開の
直接の基底クラスへのポインタに暗黙に変換することができる。
メンバへのアクセスは,そのメンバを名付けているクラスによって影響される。名付けているクラスとは,そのメン
バの名前を探して見つけだす場としてのクラスとする。
参考
このクラスは,
《修飾付き識別子》のように明示的であってもよいし,クラスメンバアクセス演算子(
##
)
を使ったときのように暗黙的(これには,暗黙の
:V;
が付加されるときも含む。)であってもよい。
クラスメンバアクセス演算子 及び 《修飾付き識別子》の両者が メンバを名指すのに使ってある(
$V
33
など )
場合,メンバを名付けているクラスは,
《修飾付き識別子》
( すなわち
)の《入れ子名前指定子》によって名指され
たクラスとする。メンバ
は,それがクラス
で名付けられている場合,次の条件のいずれかが成立するとき,ア
クセス可能とする。
―
が
のメンバとして公開である。
―
が
のメンバとして非公開であって,かつクラス
のメンバ 又は 随伴で参照している。
―
が
のメンバとして限定公開であって,かつクラス
のメンバ 若しくは 随伴で参照しているか,
がクラス
の派生クラス
のメンバ 若しくは 随伴で参照している(このとき,
は
のメンバとして
非公開 又は 限定公開となる。)
。
―
参照点でアクセス可能な
の基底クラス
が存在し ,かつ
がクラス
で名付けられている場合にア
クセス可能となっている。
例
"&
6
Q
3
&
"! &
R&
"
3
6
Q
R&
"!
Q
V
%
L&
''
B>3
"!
は暗黙に
6!
にキャストでき,
R
''
は,
6
中の
をアクセスできる。
クラスメンバアクセス演算子が,暗黙の
:V;
も含め,非静的データメンバ 又は 非静的メンバ関数のアクセ
スに使われる場合,その参照は,左演算対象(
:(;
演算子のときはポインタとみなされる。)が,右演算対象を名付け
ているクラスへのポインタに暗黙変換できないとき,不適格とする。
参考
この要件は,名指されたメンバはアクセス可能でなければならないとする要件に付加される。
アクセス宣言
基底クラスのメンバのアクセスは,派生クラス宣言内で《修飾付き識別子》を付記することに
よって派生クラス内で変更することができる。この付記をアクセス宣言という。
:
アクセス宣言 《修飾付き識別子》
&;
の効果は,
:
《修飾付き識別子》
&
;
の宣言と同等とする。
例
6
Q
3
$&
$L&
R&
注
アクセス宣言は,推奨しない。同じことをするのに,メンバの《
宣言》
(
)のほうがより良い方法である。初期の
言
語の版では,アクセス宣言はもっと制限されていた。単純化の視点から,アクセス宣言をを一般化し,
《
宣言》と同一にした。プロ
グラマには,新しいコード を書くときに,アクセス宣言の新機能よりも,
《
宣言》を使うことを推奨する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
"
3
6
Q
&
3
&
&
3
&
&
R&
#
3
"
Q
&
3
"33&
''
"33
へのアクセスに調整
"33$&
''
633$
へのアクセスに調整
633$L&
''
633$L
へのアクセスに調整
&
&
3
"33&
''
"33
へのアクセスに調整
&
R&
5
3
#
Q
&
R&
#0 &
50 &
外部関数
は,
,
$
,
$L
,
及び
の名前だけを使うことができる。関数
は,
#
のメンバなので,
,
,
$
,
$L
,
,
,
,
,
,
及び
の名前を使うことができ,
は使うことができない。
関数
は,
"
のメンバなので,
,
,
,
$
,
$L
,
,
及び
のメンバを使うことができる。関数
は,
#
の公開 及び 限定公開の名前,すなわち,
,
$
,
$L
,
及び
( 公開),並びに
及び
( 限定公
開)を使うことができる。同様に,外部関数
は,
,
$
,
$L
,
,及び
しかアクセスできない。
#
を
5
の限定公開 又は 非公開の基底クラスにしたときには,
は以前と同じにアクセスできるが,
は何も
アクセスできなくなる。
随伴クラス 及び 随伴関数
クラスの随伴とは,そのクラスのメンバではないが,そのクラスの非公開 又は
限定公開メンバの名前を使うことのできる関数 又は クラスとする。クラスの随伴の名前は,そのクラスの有効範囲
内にはなく,メンバアクセス演算子(
##
)でアクセスされることもない( 別のクラスのメンバとなっている場合を
除く。)
。
例
次の例は,メンバと随伴との違いを示す。
5
Q
&
P5!
&
3
P &
R&
P5!
Q
V
%
&
R
533P
Q
%
&
R
Q
5
&
P0
L.
&
(PL
. &
R
クラスを随伴と宣言することで,随伴関係を供与する側のクラスの非公開 及び 限定公開メンバの名前が,随伴と
なるクラスのメンバ宣言の中でアクセス可能となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
参考
これは,非公開 及び 限定公開の名前が,随伴クラスのメンバ関数からも( 関数が互いに随伴であるか
のように)アクセスすることができ,随伴クラスの静的データメンバ定義からもアクセスすることができ
ることを意味する。これはまた,随伴関係を供与する側のクラスの非公開型名 及び 限定公開型名が,随
伴クラスの入れ子クラスの《基底節》の中で使えることを意味する。しかし,随伴クラスの中の入れ子ク
ラスのメンバ宣言が,随伴関係を供与する側のクラスの非公開メンバ 及び 限定公開メンバの名前をアク
セスすることはできない。随伴クラスの《基底節》は,メンバ宣言の一部分ではないので,その中から随
伴関係を供与する側のクラスの非公開メンバ 及び 限定公開メンバの名前をアクセスすることはできない。
例
6
Q
"
Q
R&
5&
R&
5
3
633"
Q
''
不適格
3
633"
は,
5
の基底箇条
''
ではアクセスできない。
633"
&
''
B>3
633"
を
5
のメンバ宣言に使える。
J
3
633"
Q
''
B>3
633"
を
5
のメンバ宣言に使える。
633"
&
''
不適格
3
633"
は,
5
の入れ子クラスの
R&
''
メンバ宣言には使えない。
R&
クラスに対する随伴宣言では,
《詳述型指定子》を使わなければならない
。クラスを随伴宣言内で定義してはな
らない。
例
5
Q
Q
%
L..
R&
J&
R&
J
Q
S533T&
''
B>3
J
は
5
の随伴
R&
KQ
S533T&
''
エラー
3
533
は非公開
R&
随伴宣言で最初に宣言された関数は,外部結合(
#
)とする。そうでなければ ,関数はもとの結合のままになる
(
)
参照)
。
随伴宣言が,多重定義された名前 又は 演算子を参照するとき,仮引数型によって指定された関数だけを随伴とする。
例
クラス
5
のメンバ関数が,クラス
J
の随伴になることができる。
JQ
!
533 &
''
(((
R&
関数がクラスの随伴宣言内で定義できるのは,クラスが非局所クラス(
*
)であり,関数名が修飾なしであって,
関数が名前空間有効範囲をもつときとし ,かつそのときに限る。
例
@
Q
Q
R
''
@
の随伴である大域的な
の定義
R&
''
これは,メンバ関数定義ではない。
これらの関数は,暗黙的にインラインとする。クラスの中で定義された随伴関数は,それを定義したクラスの( 字句
的な )有効範囲にあるとする。クラスの外で定義された随伴関数定義は,クラス有効範囲にはない(
参照)
。
随伴宣言の《宣言指定子列》の中に,
《記憶域種別指定子》は指定できない。
随伴宣言で指定する名前は,随伴宣言を含むクラスの有効範囲からアクセス可能でなければならない。随伴宣言の
意味は,その随伴宣言がクラスの《メンバ指定》の非公開部分,限定公開部分 又は 公開部分(
*
)のど の部分に現
れても同じとする。
随伴は,継承されないし ,推移律も満たさない。
注
《詳述型指定子》の《クラスキー》を書かなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
6
Q
"&
&
R&
"
Q
7&
R&
7
Q
6!
Q
V))&
''
エラー
3
6
の随伴の随伴ではあるが
R
''
7
は
6
の随伴ではない。
R&
#
3
"
Q
6!
Q
V))&
''
エラー
3
6
の随伴の派生クラスではあるが
R
''
#
は
6
の随伴ではない。
R&
随伴宣言が局所クラス(
*
)の中にあり,指定した名前が修飾なしの名前である場合,それを取り囲む最も内側の
非クラスの有効範囲の外側の有効範囲を無視して先行する宣言を検索する。関数に対する随伴宣言に先行する宣言が
ない場合,そのプログラムは不適格とする。クラスに対する随伴宣言に先行する宣言がない場合,指定されたクラス
は,それを取り囲む最も内側の非クラスの有効範囲に属する。ただし,指定されたクラスの名前は,その後続部分で
参照されたとしても,それを取り囲む最も内側の非クラスの有効範囲に対応する宣言が現れるまで,名前検索で見つ
からない。
例
5&
&
Q
J&
&
6Q
5&
''
B>3
しかし ,
5
は局所クラスであり
335
ではない。
J&
''
B>
K&
''
B>3
局所クラス
K
の導入。
&
''
エラー
3
33
は見ない。
&
''
B>
&
''
エラー
R&
5
!&
''
B>3
しかし
335
は見つかる。
K
!$&
''
エラー
3
K
は見つからない。
R
#
限定公開メンバのアクセス
派生クラスの随伴関数 又は メンバ関数が,基底クラスの限定公開の,非静的メ
ンバ関数 又は 非静的データメンバを参照している場合は,
のここまでで規定したアクセス検査に追加して,更
に別のアクセス検査を行う。
。メンバへのポインタ(
#
)を形成している場合を除き,アクセスは,派生クラ
ス自体( 又は そのクラスの任意の派生クラス)へのポインタ,参照,又は そのオブジェクト自体を介したものでな
ければならない(
#
参照)
。アクセスが メンバへのポインタを形成している場合,
《入れ子名前指定子》は,派生ク
ラス( 又は そのクラスの任意の派生クラス)を名指していなければならない。
例
"
Q
3
&
&
R&
#L
3
"
Q
R&
注
この追加の検査は,他のメンバ,つまり,静的データメンバ 又は 列挙子メンバ定数には適用されない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
#+
3
"
Q
"!
#L!
#+! &
"!
#L! &
R&
"!
#L!
L
#+!
+
Q
V
%
L&
''
不適格
LV
%
+&
''
不適格
+V
%
*&
''
B>3
(
#+
を介してアクセス)
+V"33
%
M&
''
B>3
( 名付けクラスは
"
だが,
''
#+
を介してアクセス)
"33!
P"
%
0"33
&
''
不適格
"33!
P"+
%
0#+33&
''
B>3
(
0#+33
の型は
"33!
となる。)
"33
%
/&
''
B>3
( 静的メンバへの参照だから )
#+33
%
-&
''
B>3
( 静的メンバへの参照だから )
R
#+33"!
#L!
L
Q
V
%
L&
''
不適格
LV
%
+&
''
不適格
%
*&
''
B>3
(
を介してアクセス)
"33
%
M&
''
B>3
(
を介してアクセス,修飾は無視)
"33!
P"
%
0"33
&
''
不適格
"33!
P"+
%
0#+33&
''
B>
%
/&
''
B>3
(
は静的メンバを参照するから )
"33
%
-&
''
B>3
(
"33
は静的メンバを参照するから )
R
"!
#L!
L
#+!
+
Q
V
%
L&
''
不適格
LV
%
+&
''
不適格
+V
%
*&
''
不適格
R
(
仮想関数へのアクセス
仮想関数に対するアクセス規則(
)は,その宣言によって決まり,後でそれに上書
きする関数に対する規則には影響されない。
例
"
Q
3
&
R&
#
3
"
Q
3
&
R&
Q
#
&
"!
%
0&
#!
%
0&
V &
''
B>3
"33
は公開
''
#33
が呼び出される。
V &
''
エラー
3
#33
は非公開
R
アクセスは,メンバ関数が呼び出される対象となっているオブジェクトを示す式の型( 上の例では
"!
)を使って,呼
出し地点で検査する。メンバ関数のアクセスは,それが定義されているクラス( 上の例では
#
)の中では,一般に分
からない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
)
複数アクセス
多重継承グラフの複数のパスを通して達することのできる名前のアクセスは,その最大のアク
セスを与えるパスによるアクセスとする。
例
I
Q
3
&
R&
6
3
I
Q
R&
"
3
I
Q
R&
7
3
6
"
Q
Q
I33 &
R
''
B>
R&
I33
は,
"
を介する公開のパスを使って
733
から利用できるので,アクセス可能となる。
入れ子クラス
入れ子クラスのメンバは,それを取り囲むクラスのメンバに対して特別なアクセスをもたない。
また,それを取り囲むクラスに対して随伴関係を供与しているクラス 及び 関数に対しても特別なアクセスをもたな
い。これらすべては,通常のアクセスの規則(
)に従わなければならない。入れ子クラスを取り囲んでいるクラス
のメンバは,入れ子クラスのメンバに対して特別なアクセスをもたない。したがって,通常のアクセスの規則(
)
に従わなければならない。
例
8
Q
&
"
Q
R&
<
Q
"
&
''
エラー
3
833"
は非公開
&
8!
Q
V
%
&
''
エラー
3
833
は非公開
R
R&
<!
C
Q
V&
''
エラー
3
<33
は非公開
R
R&
参考
入れ子クラスの《基底節》は,入れ子クラス自体の宣言の一部である(そして,入れ子クラスのメンバ
宣言の一部ではない。)ので,
《基底節》から,それを取り囲むクラスの非公開メンバを参照してもよい。
例
7
Q
6
Q
R&
6
!&
''
B>
"
3
6
''
B>
Q
6
!&
''
B>3
クラス
6
に名前
6
が含まれるから
7336
!&
''
エラー
3
7336
はアクセスできない。
"
!&
''
B>3
クラス
"
に名前
"
が含まれるから
733"
!&
''
エラー
3
733"
はアクセスできない。
R&
R&
特殊メンバ関数
特殊メンバ関数は,省略時コンストラクタ(
),コピーコンストラクタ,コピー代入演算
子(
) 及び デストラクタ(
)とする。
の規定を除き,プログラムがクラス型の特殊メンバ関数を明示
的に宣言していない場合,処理系は,その関数を暗黙に宣言する。その関数が用いられている場合には,
,
及び
で規定するとおり,処理系がそれを暗黙に定義する。プログラムは,暗黙に宣言される特殊メンバ関数を
定義してはならない。プログラムは,暗黙に宣言される特殊メンバ関数を明示的に参照してよい。
例
プログラムは,暗黙に宣言される特殊メンバ関数を,明示的に呼び出したり,アドレスを取り出したり,メ
ンバへのポインタを生成したりしてもよい。
6
Q
R&
''
633%
は,暗黙に宣言されている。
"
3
6
Q
"0
%
"
0 &
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
R&
"0
"33%
"0
Q
V633
%
&
''
適格
!&
R
参考
特殊メンバ関数は,クラス型のオブジェクトの生成,コピー 及び 解体の方法 並びに 他の型の値への変
換方法に影響を及ぼす。これらの特殊メンバ関数は,暗黙に呼び出されることが多い。
特殊メンバ関数は,通常のアクセス規則(
)に従う。
例
コンストラクタを
として宣言することによって,派生クラス,随伴クラス 及び 随伴関数を使っ
てだけオブジェクトを生成できることが保証される。
コンスト ラクタ
コンストラクタには,名前がない。関数指定子(
)
)の並び( あってもなくてもよい。)
とそれに続くコンストラクタのクラス名 及び 仮引数並びを記述する特別な宣言子構文によって,コンストラクタの
宣言 又は 定義を行う。その宣言では,コンストラクタのクラス名を囲む括弧があっても無視する。
例
7
Q
3
7 &
''
コンストラクタの宣言
R&
7337
Q
R
''
コンストラクタの定義
コンストラクタは,そのクラス型のオブジェクトの初期化を行う。コンストラクタは,名前をもたないので,名前
検索によってコンストラクタが見つかることがない。しかし ,関数記法(
#
)を使った明示的型変換のときには,
コンストラクタが呼び出されてオブジェクトを初期化する。
参考
クラス型のオブジェクトの初期化は,
(
で規定する。
クラスに名前付けした型定義名は,クラス名(
)
)となる。しかし ,クラスに名前付けした型定義名は,コンス
トラクタ宣言における宣言子の中の識別子として用いてはならない。
コンストラクタは,
(
)又は
(
*
)としてはならない。コンストラクタは,
,
又は
のオブジェクトに対して呼び出すことができる。コンストラクタは,
,
又は
(
*
)と宣言してはならない。
及び
の意味規則(
)#
)は,構築中のオブ
ジェクトには適用されない。それらの意味規則は,最派生クラスのオブジェクト(
)に対する構築が完了したとき
に初めて有効となる。
クラス
の省略時コンストラクタは,実引数なしで呼び出すことができるクラス
のコンストラクタとする。ク
ラス
に対する利用者宣言のコンストラクタがない場合,省略時コンストラクタが暗黙に宣言される。暗黙に宣言
された省略時コンストラクタは,そのクラスの
のメンバとする。コンストラクタが暗黙に宣言され
た省略時コンストラクタであって,次の条件がすべて成り立つ場合,そのコンストラクタは自明であるという。
―
そのクラスは,仮想関数(
)も仮想基底クラス(
)ももたない。
―
そのクラスの直接基底クラスのすべてが,自明なコンストラクタをもつ。
―
そのクラスのすべてのクラス型( 又は その配列型)の非静的データメンバについて,それぞれのクラスが
自明なコンストラクタをもつ。
そうでない場合,コンストラクタは,自明でないという。
暗黙に宣言された省略時コンストラクタは,そのクラス型のオブジェクトの生成(
)に使われたとき,暗黙に
定義される。暗黙に定義された省略時コンストラクタは,メンバ初期化子並び(
(
)が空で関数本体が空の省略
時コンストラクタを利用者が書き,それを実行した場合と同じ初期化を行う。利用者が書いた省略時コンストラクタ
が不適格の場合,そのプログラムは不適格とする。クラスに暗黙に宣言された省略時コンストラクタが暗黙に定義さ
れる前に,そのクラスの基底クラス 及び 非静的データメンバに対して暗黙に宣言された省略時コンストラクタのす
べてが,暗黙に定義されていなければならない。
参考
暗黙に宣言された省略時コンストラクタは,例外指定(
#
)をもつ。
次の場合に,省略時コンストラクタが,暗黙に呼び出される。
―
初期化子(
#
)を付けずに定義した静的記憶域期間 又は 自動記憶域期間(
)
,
)
)のクラスオブ
ジェクトを生成する場合。
―
《生成初期化子》のない《
<
式》
(
#
)によって動的記憶域期間のクラスオブジェクトを生成する場合。
―
明示的型変換の構文(
#
)を使った場合。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
オブジェクトに対する省略時コンストラクタが暗黙に用いられているが,そのコンストラクタにアクセス(
)す
ることができない場合,そのプログラムは不適格とする。
参考
基底クラス 及び 非静的データメンバに対するコンストラクタが呼び出される順序 及び それらのコンス
トラクタの呼出しに実引数を指定する方法は,
(
で規定する。
クラス
のコピーコンストラクタは,型
0
又は 型
0
を第
仮引数にもつ。
参考
コピーコンストラクタの詳細は,
で規定する。
共用体のメンバは,自明でないコンストラクタをもつクラス型( 又は その配列型)としてはならない。
コンストラクタに返却値の型を(
でさえも)指定してはならない。コンストラクタ本体の
文に返却値
の型を指定してはならない。コンストラクタのアドレスを取り出してはならない。
関数記法の型変換(
#
)によって,その型の新しいオブジェクトを生成することができる。
参考
その構文は,コンストラクタの明示的な呼出しに似ている。
例
$$
%
L
+(* &
,(N
L(+
&
この方法で作られたオブジェクトは,名前をもたない。
参考
一時オブジェクトの生存期間は,
で規定する。
参考
明示的なコンストラクタの呼出しは,左辺値を生じない(
参照)
。
参考
言語構成要素の中には,構築中に使われたときには特別な意味規則をもつものがある(
(
及び
)
参照)
。
定値オブジェクトの構築中に,オブジェクト 又は その部分オブジェクトの値を,コンストラクタの
ポインタ
から直接 又は 間接に得たのではない左辺値を介してアクセスした場合,それによって得たオブジェクト 又は 部分オ
ブジェクトの値は,未規定とする。
例
7&
7
! &
7
&
7
3
.
&
&
7
&
7!
%
(
!
L..&
''
(
の値は未規定
V
%
L&
(
!
L..
''
(
の値は未規定
Z4Z&
一時オブジェクト
クラス型の一時オブジェクトは,次の文脈で作られる。
―
右辺値の参照への結合(
#
)
―
右辺値の返却(
((
)
―
右辺値を作る変換(
,
#*
,
#
及び
#
参照)
―
例外の送出(
#
)
―
ハンド ラの入口(
#
)
―
初期化(
#
)の幾つかの場合
参考
例外オブジェクトの生存期間は,
#
で規定する。
一時オブジェクトの生成が避けられる場合(
)であっても,すべての意味規則上の制約は,一時オブジェクトが
生成されたかのように遵守しなければならない。
例
コピーコンストラクタを呼び出さない場合であっても,アクセス可能性(
)などのすべての意味規則の
制約が満たされなければならない。
例
5
Q
''
(((
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
''
(((
5 &
5
50 &
X5 &
R&
5
5 &
Q
5
L &
5
%
5+ &
%
&
R
ここで,処理系は,
に渡す前に
5
のコピーコンストラクタを用いて一時変数に
5+
を構築してもよ
いし ,実引数を保持する領域に
5+
を直接構築してもよい。更に,
5
のコピーコンストラクタで
にコ
ピーする前に,
5+
の結果を保持するための一時変数を使ってもよいし ,
の結果を
に構築して
もよい。しかし ,
%
のような式の場合,望ましくない
の別名問題が起こるのを避けるために,実
引数
又は
の結果に対する一時変数が必要となる。
処理系は,自明でないコンストラクタ(
)をもつクラスの一時オブジェクトを作る場合,その一時オブジェク
トに対してそのコンストラクタを呼び出すことを保証しなければならない。同様に,自明でないデストラクタ(
)
をもつ一時オブジェクトに対しては,そのデストラクタを呼び出さなければならない。一時オブジェクトの解体は,
それを生成した地点を( 字句的に )含む完結式(
*
)の評価の最終段階で行う。その完結式の評価が例外送出で終了
する場合であっても,その最終段階で解体される。
一時変数の解体と完結式の終了とが異なる地点で行われる文脈が二つある。第
の文脈は,オブジェクトを定義す
る宣言子の初期化子の中に式が現れた場合とする。その文脈では,式の結果を保持する一時変数は,オブジェクトの
初期化完了まで存在する。オブジェクトの初期化は,一時変数からのコピーで行われる。処理系は,そのコピー中に
コピーコンストラクタを何回呼び出してもよい。一時変数は,コピーが完了した後であって,初期化の完了前 又は
完了時点で解体される。複数の一時変数が初期化子の評価において生成される場合,一時変数の解体は,その構築が
完了した順序の逆順に行われる。
第
の文脈は,参照が一時変数に結合される場合とする。参照が結合される一時変数 又は 自分自身その部分オブ
ジェクトに結合されている完全オブジェクトになっている一時変数は,次にあげ る場合を除き,参照の生存期間だけ
保持される。
―
コンストラクタ初期化子(
(
)内の参照メンバに結合される一時変数は,コンストラクタから抜け出
るまで保持される。
―
関数呼出し(
#
)内の参照仮引数に結合される一時変数は,その呼出しを含む完結式の完了まで保持さ
れる。
―
関数の
文(
((
)の返却値に結合される一時変数は,関数から抜け出るまで保持される。
これらのすべての場合において,参照を初期化する式の評価中に生成された一時変数は,参照に結合される一時変数
を除き,それを生成した完結式の完了時に,構築の完了した順序の逆順に解体される。更に,参照に結合された一時
変数の解体は,静的記憶域期間 又は 自動記憶域期間(
)
及び
)
参照)のオブジェクトの解体の順序を考慮
して行われる。つまり,
L
が一時変数の生成前に作られた静的記憶域期間 又は 自動記憶域期間のオブジェクトで
ある場合,その一時変数は,
L
が解体される前に解体される。更に,
+
が一時変数より後に生成された静的記
憶域期間 又は 自動記憶域期間のオブジェクトである場合,その一時変数は,
+
が解体された後で解体される。
例
7
Q
''
(((
3
7 &
7 &
7
)
70
70 &
X7 &
R&
7
L&
70
%
7L-
)
7+* &
7
+&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
式
7L- )7+*
は,三つの一時変数を生成する。第
の一時変数
L
は,式
7L-
の結果を保持し,第
の一時変数
+
は,式
7+*
の結果を保持し,第
の一時変数
*
は,その二つの式の加算結果を保持す
る。一時変数
*
は,その後,参照
に結合される。
L
及び
+
のど ちらが先に作られるかは未規定とす
る。
L
を
+
より前につくる処理系では,
L
の前に
+
が解体されることが保証される。
L
及び
+
は,
)
の参照仮引数に結合される。それらの一時変数は,
)
の呼出しを含む完結式の終了
時に解体される。一時変数
*
は,参照
に結合されるので,
の生存期間の終了,つまり,プログラム
の終了の時点で解体される。更に,
*
の解体順には,静的記憶域期間の他のオブジェクトの解体順が考慮
される。つまり,
L
が
*
より前に構築され,
*
が
+
より前に構築されているので,
+
は
*
よ
り前に解体され,
*
は
L
より前に解体される。
変換
コンストラクタ 及び 変換関数を用いて,クラスオブジェクトの型変換を指定することができる。その
変換を,利用者定義変換といい,暗黙の型変換(
),初期化(
#
) 及び 明示的型変換(
#
及び
#*
参照)に
用いる。
利用者定義変換は,あいまいでない場合だけ適用される(
及び
参照)に。変換は,アクセス制御規則
(
)に従う。アクセス制御は,あいまいさの解決(
)の後で適用される。
参考
関数呼出しにおける変換の使い方を次の例 及び
に示す。
一つの値には,高々一つの利用者定義変換(コンストラクタ 又は 変換関数)だけが暗黙に適用される。
例
5
Q
''
(((
3
&
R&
J
Q
''
(((
3
5 &
R&
J
&
%
&
''
エラー
3
''
(
5 (
は,試みられない。
%
5 &
''
B>3
(
5 (
利用者定義変換は,あいまいでない場合にだけ暗黙に用いられる。派生クラス内の変換関数 及び 基底クラス内の
変換関数が同じ型に変換しない場合,派生クラス内の変換関数は,基底クラス内の変換関数を隠ぺいしない。
例
5
Q
3
''
(((
&
R&
J
3
5
Q
3
''
(((
&
R&
J0
Q
Q
''
不適格
3
''
533
なのか
J33
なのか
''
(((
R
R
コンスト ラクタによる変換
関数指定子
なしで宣言され,一つの仮引数で呼び出すことができる
コンストラクタは,第
仮引数の型をコンストラクタのクラスの型へ変換することを指定する。このコンストラクタ
を,変換コンストラクタという。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
##
例
5
Q
''
(((
3
5 &
5
!
%
. &
R&
5
Q
5
%
L&
''
%
5L
5
%
Y=Y&
''
%
5Y=Y .
%
+&
''
%
5+
* &
''
5*
R
明示的コンストラクタは,直接初期化構文(
#
) 又は キャスト(
#*
及び
#
参照)が明示的に用いられてい
る場合にだけ,明示的でないコンストラクタと同じようにオブジェクトを構築する。省略時コンストラクタは,明示
的コンストラクタであってもよい。そのコンストラクタは,省略時初期化 又は 値初期化(
#
)を実行するために使
われる。
例
K
Q
3
K &
K &
''
(((
R&
K
&
''
B>3
省略時初期化を行う。
K
L
%
L&
''
エラー
3
暗黙の変換がない。
K
*
%
KL &
''
B>3
直接初期化構文を使用
K
+L &
''
B>3
直接初期化構文を使用
K!
%
KL &
''
B>3
直接初期化構文を使用
K
M
%
K L&
''
B>3
明示的なキャストを使用
K
/
%
PKL
&
''
B>3
明示的なキャストを使用
変換コンストラクタの一つとして,明示的でないコピーコンストラクタ(
)がある。暗黙に宣言されたコピー
コンストラクタは,明示的コンストラクタではない。暗黙の型変換によって,暗黙に宣言されたコピーコンストラク
タを呼び出してもよい。
変換関数
クラス
のメンバ関数で,次の形式の名前をもつものは,型
から《変換型識別子》で指定す
る型へ変換することを指定する。
変換関数識別子
3
変換型識別子
変換型識別子
3
型指定子列
変換宣言子
変換宣言子
3
ポインタ演算子
変換宣言子
このメンバ関数を変換関数という。
《型指定子列》には,クラス,列挙体 及び 型定義名を宣言してはならない。仮引
数の型 及び 返却値の型を指定することもできない。変換関数(
#
)の型は,
:
仮引数がなく《変換型識別子》を
返す関数
;
とする。変換関数は,
(
0
修飾付きでもよい )オブジェクトを,次に示す型に変換するために用いてはなら
ない
。
―
同じ(
0
修飾付きでもよい )オブジェクト型( 又は それへの参照)
―
その型の(
0
修飾付きでもよい)基底クラス( 又は それへの参照)
―
(
0
修飾付きでもよい)
例
注
その変換関数は,変換を行うために直接呼び出されることはないが,変換関数を宣言し,基底クラスの仮想変換関数の呼出しを介して,
結果として変換関数が呼び出される可能性もある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#(
5
Q
''
(((
3
&
R&
5
Q
%
&
%
&
%
&
R
この三つの場合は,いずれも代入される値は,
533
によって変換される。
利用者定義変換の利用は,代入 及び 初期化だけに限定されない。
例
5
5
Q
%
2
L)
3
.&
%
00
2
)
3
&
Q
''
(((
R
R
《変換型識別子》は,関数型 又は 配列型を表すものであってはならない。
《変換関数識別子》中の《変換型識別子》
は,
《変換宣言子》の最長可能並びとする。
参考
それによって,宣言子演算子
!
が式の一部とみなされてあいまいとなることはない。
例
0(
!&
''
構文エラー
''
0(
!
と字句解析する。
''
0(
!
ではない。
この
!
は,ポインタ宣言子であって,乗算演算子ではない。
変換関数は,継承される。
変換関数は,仮想であってもよい。
デスト ラクタ
クラス定義内でデストラクタを宣言する特別の宣言子構文は,省略可能な関数指定子(
)
)
の後に
X
が続き,その後にデストラクタのクラス名が続き,更にその後に空の仮引数並びが続く。その宣言では,
X
及び それに続くデストラクタのクラス名が,省略可能な括弧で囲まれていてもよいが,その括弧は無視される。クラ
スに名前付けする型定義名は,クラス名(
)
)とする。しかし ,クラスに名前付けする型定義名は,デストラクタ
宣言のための宣言子の識別子として用いてはならない。
デストラクタは,そのクラス型のオブジェクトの解体に使われる。デストラクタには,仮引数がなく,返却値の型を
(
でさえも)指定してはならない。デストラクタのアドレスを取り出してはならない。デストラクタは,
としてはならない。デストラクタは,
,
又は
オブジェクトに対して呼び出すこと
ができる。デストラクタは,
,
又は
(
*
)と宣言してはならない。
及び
の意味規則(
)#
)は,解体中のオブジェクトには適用されない。それらの意味規則は,最派生クラス
のオブジェクト(
)の解体が始まると,適用されない。
クラスが利用者宣言デストラクタをもたない場合,デストラクタが暗黙に宣言される。暗黙に宣言されたデストラ
クタは,クラスの
メンバとする。デストラクタが暗黙に宣言されたデストラクタであって,次の条
件がすべて成り立つ場合,そのデストラクタは自明であるという。
―
そのクラスの直接基底クラスのすべてが,自明なデストラクタをもつ。
―
そのクラスのすべてのクラス型( 又は その配列型)の非静的データメンバについて,それぞれのクラスが
自明なデストラクタをもつ。
そうでない場合,デストラクタは,自明でないという。
暗黙に宣言されたデストラクタは,そのクラス型のオブジェクトの解体(
)
)に使われたとき,暗黙に定義され
る。デストラクタが暗黙に定義されているクラスが次のいずれかをもつ場合,そのプログラムは不適格とする。
―
アクセスできないデストラクタをもつクラス型( 又は その配列型)の非静的データメンバ
―
アクセスできないデストラクタをもつ基底クラス
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#)
クラスに暗黙に宣言されたデストラクタが暗黙に定義される前に,そのクラスの基底クラス 及び 非静的データメン
バに対して暗黙に宣言されたデストラクタのすべてが,暗黙に定義されていなければならない。
参考
暗黙に宣言されたデストラクタは,例外指定(
#
)をもつ。
デストラクタの本体が実行され ,その本体の中で割り当てられた自動記憶域期間のオブジェクトが解体された後,
クラス
に対するデストラクタは,
の直接のメンバに対するデストラクタ 及び
の直接基底クラスに対するデ
ストラクタを呼び出す。更に,
が最派生クラス型(
(
)の場合には,その仮想基底クラスに対するデストラク
タも呼び出す。すべてのデストラクタは,修飾名付きで参照されたかのようにして,すなわち,より派生したクラス
で上書きしているかもしれないあらゆる仮想デストラクタを無視して,呼び出される。基底クラス 及び メンバの解
体の順序は,コンストラクタの完了の逆順とする(
(
参照)。デストラクタの中の
文(
((
)は,呼出
し元に戻る前に,それのメンバ 及び 基底クラスのデストラクタが呼び出されて,呼出し元に直接戻らないこともあ
る。配列の要素に対するデストラクタは,その構築の順序の逆順に呼び出される(
(
参照)
。
デストラクタは,仮想(
) 又は 純粋仮想(
)と宣言することができる。クラス 又は その派生クラスの
オブジェクトが,一つでもプログラムで生成される場合,デストラクタは定義されていなければならない。クラスが,
仮想デストラクタをもつ基底クラスをもつ場合,デストラクタは,
( 利用者宣言 又は 暗黙の宣言のいずれであっても)
仮想となる。
参考
解体中に使われたときに特別な意味規則をもつ言語構成要素がある(
)
参照)
。
共用体のメンバは,自明でないデストラクタをもつクラス型( 又は その配列型)としてはならない。
次の場合に,デストラクタは暗黙に呼び出される。
―
プログラム終了時(
(
)に,静的記憶域期間に構築されたオブジェクト(
)
)に対して
―
オブジェクトが構築されたブロックから抜け出る時(
()
),自動記憶域期間に構築されたオブジェクト
(
)
)に対して
―
構築された一時オブジェクトの生存期間が終了した時,一時オブジェクト(
)に対して
―
《
<
式》
(
#
)によって割り当てられ構築されたオブジェクトに対し ,
《
3
式》
(
##
)を使うこ
とによって
―
例外(
#
)を扱うためのいくつかの状況において
クラス型 又は その配列型のオブジェクトが宣言されたが,そのクラスのデ ストラクタをその宣言地点でアクセスで
きない場合,そのプログラムは不適格とする。デストラクタは,明示的に呼び出すこともできる。
仮想デストラクタが定義されたとき( 暗黙の定義(
)の場合も含む),位置指定でない演算子
が,そ
のデストラクタのクラスの有効範囲内で検索(
)されて,見つかったものは,アクセス可能でなければならず,
あいまいであってはならない。
参考
これによって,オブジェクトの動的な型に対応する演算子
が《
3
式》で使えることが保証
される(
#
参照)
。
デストラクタの明示的呼出しの場合,デストラクタ名は,
X
の後にデストラクタのクラス型を指す型名を付加して
表す。デストラクタの呼出しは,メンバ関数の通常の規則(
*
)に従う。すなわち,オブジェクトが,そのデストラ
クタのクラス型をもたず,そのデストラクタのクラス型から派生したクラス型でない場合,そのプログラムの挙動は
未定義とする( 但し ,空ポインタに対し
を呼び出した場合は無効果とする。)
。
例
"
Q
X"
Q
R
R&
#
3
"
Q
X#
Q
R
R&
#
#P&
"
"P&
"!
"P
%
0#P&
Q
#P("33X" &
''
"
のデストラクタ呼出し
"PVX" &
''
#
のデストラクタ呼出し
"PVX"P
&
''
#
のデストラクタ呼出し
"PV"P33X
"
&
''
"
のデストラクタ呼出し
"PV"P33X
"P
&
''
エラー
3
クラス
"
に
"P
はない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
R
参考
デストラクタの明示的な呼出しは,常に メンバアクセス演算子(
##
)を使って書かなければならな
い。特に,メンバ関数内の単項式
X5
は,デストラクタの明示的な呼出しではない(
#
参照)
。
参考
デストラクタの明示的な呼出しが必要となることは,ほとんどない。明示的な呼出しの使い方の一つと
して,位置指定付きの《
<
式》を用いて特定のアドレスに置いたオブジェクトに対する使い方がある。
そのオブジェクトの明示的な配置指定 及び その解体という使い方は,専用のハード ウェア資源を扱う場
合 及び 記憶域管理機能を書く場合に,必要となる。
例
!
$P
!
Q
&
R
5
Q
''
(((
5 &
X5 &
R&
5!
&
''
まれな特殊用法
Q
!
%
S$5 T&
5!
%
5+++ &
''
ST
を使い初期化する。
&
V533X5 &
''
後始末
R
オブジェクトに対してデストラクタが呼び出されると,そのオブジェクトは存在しなくなる。生存期間の終了した
オブジェクトに対してデストラクタが呼び出された場合(
)の動作は,未定義とする。
例
自動記憶域期間のオブジェクトに対してデストラクタが明示的に呼び出された場合,そのブ ロックでは,
そのオブジェクトの暗黙の解体を後で通常ど おり行うことになる。この場合の動作は,未定義とする。
参考
スカラの型名(
#
)に対して,デストラクタの明示的な呼出しの記法を使うことができる。それを許
すことによって,型に対するデストラクタがあるか否かを知らなくても,コード を書くことができる。
例
<&
<!
&
''
(((
V<33X< &
#
空き領域
クラス
に対するすべての割付け関数は,
(
と明示的に宣言しなくても)静的メンバとなる。
例
6&
"
Q
!
$P
6! &
R&
#L
3
"
Q
R&
6!
&
Q
#L&
''
"33
$P
6!
を呼び出す。
#LST&
''
33
ST$P
を呼び出す。
#L&
''
不適格
3
33
$P
が隠ぺい
''
されている。
R
オブジェクトが《
3
式》
(
##
)を用いて削除され る場合,解放関数( 非配列オブジェクトには
を用い,配列には
ST
を用いる。)が,オブジェクトの占有していた記憶域を解放する
ために( 暗黙に )呼び出される(
)
参照)
。
《
3
式》が単項演算子
33
で始まっている場合,解放関数の名前は,大域的有効範囲で検索される。そうでは
なく,クラスオブジェクトを解放するために《
3
式》が使われていて,そのクラスオブジェクトの静的型が仮想
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#*
デストラクタをもっている場合,その動的型の仮想デストラクタ(
)の定義を検索して見つかった解放関数が用
いられる
。更にそうでない場合であって,クラス
又は その配列型のオブジェクトの解放のために《
3
式》
が使われている場合,そのオブジェクトの静的型 及び 動的型は一致しなければならず,解放関数の名前は,
の有
効範囲内で検索される。その検索で名前が見つからなかった場合,大域的有効範囲内で名前が検索される。その検索
の結果があいまいとなるか,アクセスできない場合,そのプログラムは不適格とする。
《
3
式》が実行されるとき,選択された解放関数が,解放する記憶域ブロックの先頭アドレスを第
実引数と
し ,
個の仮引数をもつ解放関数であれば,そのブロックの大きさを第
実引数として,呼び出される
。
クラス
に対するすべての解放関数は,
(
明示的にと宣言されていなくても)静的メンバとなる。
例
5
Q
''
(((
! &
ST!
$P &
R&
J
Q
''
(((
!
$P &
ST!
&
R&
メンバの割付け関数 及び 解放関数は,静的なので,仮想とはならない。
参考
しかし,
《
3
式》中の《キャスト式》がクラス型のオブジェクトを参照する場合,デストラクタが仮
想のときは,そのオブジェクトの動的型になっているクラスの有効範囲内で実際に呼び出す解放関数を検
索するので,同じ効果となる。
"
Q
X" &
!
$P &
R&
#
3
"
Q
! &
R&
Q
"!
%
#&
&
''
行
L
3
#33
!
を使う。
R
この例では ,デ スト ラクタが 仮想なので ,クラス
#
の非配列オブ ジェクトの記憶域は ,
#33
が解放する。
参考
《
3
式》中の《キャスト式》が,クラス型のオブジェクトの配列を参照している場合には,仮想デ
ストラクタは,呼び出される解放関数の選択に影響を与えない。
例
"
Q
X" &
ST!
$P &
R&
#
3
"
Q
ST!
$P &
R&
Q
#!
%
#ST&
ST&
''
#33
ST
! $P
を使う。
"!
%
#ST&
注
&
の配列版に対しては,同様の名前検索は必要としない。その理由は,
の要請によって,この場合には,
《
式》の演算対象の静的型は,その動的型と同じだからである。
注
《
式》中の静的型が動的型と異なっており,デストラクタが仮想でない場合,ブロックの大きさは正しくないことがあるが,そ
の場合の振る舞いは,
で定めるとおり未定義となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
ST
&
''
未定義の動作
R
解放関数のアクセス検査は,静的に行われる。したがって,静的に見つかる関数と実際に実行される関数とが異な
るとしても,静的に見つかる解放関数は,アクセス可能でなければならない。
例
前の例の
''
行
L
で,
"33
が
の場合,
《
3
式》は不適格となる。
(
初期化
クラス型( 又は その配列型)のオブジェクト(
0
修飾付きでもよい。)に対し初期化子が指定されな
い場合 又は 初期化子が
の形の場合,オブジェクトは,
#
で規定するとおり初期化される。初期化子がない場合,
オブジェクトは省略時初期化が行われる。初期化子が
の場合,オブジェクトは値初期化が行われる。
クラス型( 又は その配列型)のオブジェクトを,明示的に初期化することができる(
(
及び
(
参照)
。
クラスオブジェクトが( 暗黙に 又は 明示的に )初期化される場合,コンストラクタは,その添字順に配列要素ご
とに呼び出される(
参照)
。
参考
配列要素のデストラクタは,その構築の逆順に呼び出される。
(
明示的初期化
クラス型のオブジェクトを,括弧の付いた《式並び》によって初期化することができる。ここ
で,
《式並び》は,オブジェクトを初期化するために呼び出されるコンストラクタへの実引数並びと解釈する。別の方
法として,初期化の
%
形式を使う《初期化子》として,
《代入式》を指定することもできる。動的初期化 又は コピー
初期化のいずれかの意味規則を適用する(
#
参照)
。
例
Q
''
(((
3
&
&
&
''
(((
R&
&
L &
''
を呼び出し初期化する。
%
&
''
のコピーによる初期化を行う。
%
L + &
''
を呼び出し ,
''
L +
を作り,
にコピーする。
%
&
''
を呼び出し ,結果を
''
にコピーする。
&
''
を呼び出して初期化する。
%
*&
''
で
*
を作り,
''
にコピーする。
%
Q
L
+
R&
''
エラー
3
コンストラクタが必要となる。
参考
代入演算子の多重定義(
#
)は,初期化に影響しない。
集成体( クラス 又は 配列)が,クラス型のメンバをもち,波括弧で囲まれた《初期化子並び》によって初期化さ
れる(
#
)場合,各メンバは,対応する《代入式》によってコピー初期化が行われる(
#
参照)
。
《初期化子》の
個数が集成体のメンバ数より少ない場合,明示的に初期化されないメンバには,値初期化(
#
)が行われる。
参考
《初期化子並び》中の《代入式》が,初期化される集成体のメンバにど のように対応づけられるかは,
#
に規定する。
例
S-T
%
Q
L
L +
+
R&
ここで,
S.T
及び
S*T
の初期化のために
33
が呼び出され ,
SLT
の初期
化のために
33
が呼び出され,
S+T
,
SMT
及び
S/T
の初期化のため
に
33
が呼び出される。
5
Q
3
&
&
&
R
%
Q
OO
NN(N
,,(,
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
ここで,
(
は
で初期化され,
(
は
E
で初期化され,
(
の初期化のために
33
が呼び出される。
参考
利用者定義の型変換をもつクラス型をメンバにもつ集成体であっても,集成体に対する《初期化子並び》
中の波括弧を省略することができる(
#
参照)
。
参考
が省略時コンストラクタをもたないクラス型であって,
《初期化子》が明示的に指定されていない場合,
型
( 又は その配列型)のオブジェクトの宣言は,不適格とする(
(
及び
#
参照)
。
参考
静的記憶域期間のオブジェクトの初期化の順序は,
(
及び
()
で規定する。
(
基底クラス 及び メンバの初期化
クラスのコンストラクタの定義中で,直接基底クラスの部分オブジェク
ト,仮想基底クラスの部分オブジェクト 及び 非静的データメンバのための初期化子は,
《コンストラクタ初期化子》
によって指定することができる。その形式は,次のとおりとする。
コンストラクタ初期化子
3
3
メンバ初期化子並び
メンバ初期化子並び
3
メンバ初期化子
メンバ初期化子
メンバ初期化子並び
メンバ初期化子
3
メンバ初期化子識別子
式並び
メンバ初期化子識別子
3
33
入れ子名前指定子
クラス名
識別子
《メンバ初期化子識別子》中の名前は,コンストラクタのクラスの有効範囲内で検索され,その有効範囲内で見つ
からない場合,コンストラクタの定義を含む有効範囲内で検索される。
参考
コンストラクタのクラスが,そのクラスの直接基底クラス 又は 仮想基底クラスと同じ名前のメンバを
もつ場合,メンバ 又は 基底クラスを指す《メンバ初期化子識別子》が単一の識別子からなるときは,ク
ラスのメンバを参照するものとする。隠ぺいされた基底クラスに対する《メンバ初期化子識別子》は,修
飾名を用いて指定することができる。
《メンバ初期化子識別子》が,コンストラクタのクラス,その直接基底クラス 又は 仮想基底クラスの非静的メンバ名
でない場合,その《メンバ初期化子》は不適格とする。
《メンバ初期化子並び》は,基底クラスの型を示す任意の名
前を用いて,その基底クラスを初期化することができる。
例
6
Q
6 &
R&
6
P6&
"
Q
R&
73
6
"
Q
7 &
R&
7337 3
P6
Q
R
''
基底クラス
6
に対する《メンバ初期化子》
《メンバ初期化子識別子》が,直接の非仮想基底クラス 及び 継承した仮想基底クラスの両方を指し示すためにあいま
いとなる場合,その《メンバ初期化子》は不適格とする。
例
6
Q
6 &
R&
"3
6
Q
R&
73
6
"
Q
7 &
R&
7337 3
6
Q
R
''
不適格
3
ど ちらの
6
かわからない。
《コンストラクタ初期化子》は,そのコンストラクタのクラスのメンバである無名の共用体のメンバを初期化するこ
とができる。
《コンストラクタ初期化子》で,同じ メンバ 若し くは 同じ 基底クラスに対して,又は 同じ 共用体の複
数のメンバ( 無名の共用体のメンバを含む)に対して,複数の《メンバ初期化子》を指定した場合,その《コンスト
ラクタ初期化子》は不適格とする。
《メンバ初期化子》中の《式並び》は,
《メンバ初期化子識別子》の示す基底クラスの部分オブジェクト 又は 非静
的データメンバの部分オブジェクトの初期化に使われる。
《メンバ初期化子》の意味規則は,次のとおりとする。
―
《メンバ初期化子》中の《式並び》が空の場合,基底クラス 又は メンバの部分オブジェクトには,値初
期化が行われる(
#
参照)
。
―
そうでない場合,
《メンバ初期化子識別子》の指す部分オブジェクトは,
《式並び》を《初期化子》として直
接初期化される(
#
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
例
"L
Q
"L &
'!
(((
!'
R
"+
Q
"+ &
'!
(((
!'
R
#
3
"L
"+
Q
# &
"L
&
&
R&
#33#
3
"+)L
"L)+
)*
)M
Q
'!
(((
!'
R
#
L. &
それぞれの基底クラス 及び メンバの初期化の後には,副作用完了点(
*
)がある。
《メンバ初期化子》中の《式並
び》は,対応する基底クラス 又は メンバの初期化の一部として評価される。
ある実体( 非静的データメンバ 又は 基底クラスのいずれか )が,
《メンバ初期化子識別子》によって指定されなかっ
た場合(コンストラクタが《コンストラクタ初期化子》をもたないために《メンバ初期化子識別子》がない場合も含
む。),次のことが行われる。
―
実体が(
0
修飾付きであってもよい )クラス型( 又は その配列型)の非静的データメンバ 又は 基底ク
ラスであって,非
"
互換クラスの場合,その実体は,省略時初期化される(
#
参照)。ただし ,実体が
!
修飾型の非静的データメンバの場合,その実体のクラスには,利用者宣言の省略時コンストラクタ
がなければならない。
―
そうでない場合,実体は初期化されない。実体が,
!
修飾型 若しくは 参照型の場合,又は
!
修飾
型のメンバを( 直接 若しくは 間接に )もつ(
0
修飾付きであってもよい)
"
互換クラス型( 若しくは そ
の配列型)の場合,そのプログラムは不適格とする。
クラス
のコンストラクタ呼出しが完了した時点で,
のメンバが,コンストラクタの《メンバ初期化子》に指定
されず,省略時初期化もされず,値初期化もされず,コンストラクタ本体の実行によっても値が与えられなかった場
合,そのメンバの値は不定とする。
初期化は,次の順序で行われる。
―
まず,次の段落で規定するとおりに,最派生クラスのコンストラクタにおいてだけ,基底クラス群の有向
非循環グラフを,深さ優先で左から右への走査で出現した順に,仮想基底クラスが初期化される。ここで
:
左から右
;
とは,派生クラスの《基底指定子並び》における基底クラス名が現れる順とする。
―
次に,
《基底指定子並び》に現れる宣言順に,直接基底クラスが初期化される。
(《メンバ初期化子》の順序
は,無視される。)
―
次に,非静的データメンバが,クラスの定義中に宣言された順に初期化される。
(ここでも《メンバ初期化
子》の順序は,無視される。)
―
最後に,コンストラクタの本体が実行される。
参考
基底クラス 及び メンバの部分オブジェクトの解体が初期化の逆順になることを保証するために,これ
らの初期化は,宣言の順に行わなければならない。
仮想基底クラスを表すすべての部分オブジェクトは,最派生クラス(
)のコンストラクタによって初期化され
る。最派生クラスのコンストラクタが,仮想基底クラス
*
の《メンバ初期化子》を指定していない場合,
*
の省略時
コンストラクタが呼び出され,仮想基底クラスの部分オブジェクトを初期化する。
*
が,アクセス可能な省略時コン
ストラクタをもたない場合,その初期化は不適格とする。仮想基底クラスを指定している《メンバ初期化子》は,最
派生クラスではないど のクラスのコンストラクタの実行においても無視される。
例
H
Q
3
H &
H &
''
(((
R&
6
3
H
Q
3
6 &
6 &
''
(((
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
R&
"
3
H
Q
3
" &
" &
''
(((
R&
7
3
6
"
H
Q
3
7 &
7 &
''
(((
R&
6336
3
H
Q
'!
(((
!'
R
"33"
Q
'!
(((
!'
R
7337
Q
'!
(((
!'
R
H
L &
''
H
を使う。
6
+ &
''
H
を使う。
"
* &
''
H
を使う。
7
M &
''
H
を使う。
《メンバ初期化子》の《式並び》中の名前は,
《メンバ初期化子》が指定されたコンストラクタの有効範囲内で評価
される。
例
5
Q
&
&
&
&
3
0
&
5
3
V
Q
R
R&
この例は,
533
を
533
への参照で初期化し,
533
をコンストラクタの仮引数
の値で初期化し,
533
をコンストラクタの仮引数
の値で初期化し,そして,
533
を
533
の値で初期化する。クラス
5
のオブ
ジェクトが生成される度に,これが行われる。
参考
《メンバ初期化子》は,コンストラクタの有効範囲内で評価されるので,初期化されるオブジェクトを
参照するために,
《メンバ初期化子》の《式並び》の中で
ポインタを用いることができる。
構築中のオブジェクトに対して,メンバ関数[仮想関数(
)を含む。]を呼び出すことができる。同様に,構築
中のオブジェクトを,
演算子(
#
) 又は 動的キャスト(
#)
)の演算対象にしてもよい。しかし,基底
クラスのすべての《メンバ初期化子》の完了前に,
《コンストラクタ初期化子》中( 又は 《コンストラクタ初期化子》
から直接 若しくは 間接に呼び出される関数中)でこれらの演算を実行した場合,その演算の結果は未定義とする。
例
6
Q
3
6 &
R&
"
3
6
Q
&
3
&
"
3
6
''
未定義
3
メンバ関数を呼び出すが,
''
基底クラス
6
は,まだ初期化されていない。
Q
R
''
適格
3
基底クラスがすべて初期化されている。
R&
7
Q
3
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
7 &
R&
#
3
"
7
Q
&
3
#
3
7
''
未定義
3
メンバ関数を呼び出すが,
''
基底クラス
7
は,まだ初期化されていない。
Q
R
''
適格
3
基底クラスがすべて初期化されている。
R&
参考
)
に,構築中の仮想関数呼出し ,
及び
が適格な場合の結果を示す。それは,
構築中のオブジェクトの多相的(
1
1
)な動作を示す。
)
構築 及び 解体
非
"
互換クラス型(
*
)のオブジェクトに対して,コンストラクタの実行が始まる前 及び デ
ストラクタの実行が完了した後に,そのオブジェクトの非静的データメンバ 又は 基底クラスを参照した場合,その
動作は未定義とする。
例
5
Q
&
R&
J
3
5
Q
R&
6
Q
&
R&
"
3
6
Q
&
J
&
R&
"
&
"!
%
0&
''
B>
!
L
%
0(&
''
未定義
3
基底クラスのメンバ参照
!
C+
%
0((&
''
未定義
3
メンバのメンバ参照
6!
%
0&
''
未定義
3
基底クラス型の上方キャスト
"
&
''
の定義
5
&
!
*
%
0(&
''
B>3
5
は
7
互換クラス
5
&
もう一つの例を示す。
I
Q
&
R&
5
3
I
Q
R&
J
Q
!&
5
&
J
3
0(
''
未定義
3
5
は構築されてない。
Q
R
R&
クラス
のオブジェクトを参照するポインタ( 左辺値)を,
の直接 又は 間接の基底クラス
へのポインタ
( 参照)に,明示的 又は 暗黙に変換するためには,
の構築 及び
から直接 又は 間接に派生した直接 又は 間接
の基底クラスのすべての構築がすでに開始された後であって,それらのクラスの解体の完了前でなければならない。
そうでない場合,その変換の動作は,未定義とする。あるオブジェクト
の直接の非静的メンバへのポインタを作
る( 又は そのメンバの値をアクセスする)ためには,
の構築がすでに開始された後であって,その解体の完了前
でなければならない。そうでない場合,ポインタ値の計算( 又は メンバ値のアクセス)は,未定義の動作とする。
例
6
Q
R&
"
3
6
Q
R&
7
3
"
Q
R&
#
3
6
Q
#6! &
R&
5
Q
56! &
R&
8
3
7
#
5
Q
8
3
#
''
未定義
3
8!
から
6!
への上方キャストでは
''
8!
→
#!
→
6!
のパスを使うが,
''
#
がまだ構築されていない。
''
#7!
''
定義されている:
''
8!
→
7!
は,
8
が開始しているから定義する
''
ことができ,
7!
→
6!
は
7
が完全に構築済み
''
だから定義することができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(#
5
''
定義されている
3
5
の構築時には
''
部分束
7'"'#'6
は完全に構築されている。
Q
R
R&
メンバ関数[ 仮想関数(
)を含む]は,構築中 又は 解体中に呼び出すことができる(
(
参照)
。仮想関
数が,コンストラクタ(データメンバの《メンバ初期化子》を含む。) 又は デストラクタから直接 又は 間接に呼び
出され,その呼出しが適用されるオブジェクトが構築中 又は 解体中の場合,呼び出される関数は,コンストラクタ
自身 又は デストラクタ自身のクラス 又は その基底クラスで定義された関数とし ,コンストラクタ 又は デストラク
タのクラスから派生したクラスにおいてそれを上書きしている関数,又は 最派生オブジェクト(
)の別の基底ク
ラスのどれかにおいてそれを上書きしている関数とはしない。仮想関数の呼出しが,明示的なクラスメンバアクセス
(
##
)を用いており,オブジェクト式が,構築中 又は 解体中のオブジェクトを参照しているが,その型がコンス
トラクタ 又は デストラクタのクラスでもその基底クラスでもない場合,その呼出しの結果は,未定義とする。
例
H
Q
3
&
&
R&
6
3
H
Q
3
&
R&
"
3
H
Q
3
&
"H!
6! &
R&
#
3
6
"
Q
3
&
&
#
3
"6!
Q
R
R&
"33"H!
6!
Q
&
''
633
ではなく
H33
を呼び出す。
&
''
#33
ではなく
"33
を呼び出す。
V &
''
H
は
"
の基底クラスで,この呼出しは正しく,
''
"33
を呼び出す。
V &
''
未定義動作
3
の型は
"
の基底クラスでない。
R
演算子
(
#
)を,構築中 又は 解体中に使うことができる(
(
参照)
。
が次のいずれかの中
で使われて,その演算対象が構築中 又は 解体中のオブジェクトを参照している場合,
は,コンストラクタ 又
は デストラクタのクラスを表す
を生じる。
―
コンストラクタ(データメンバの《メンバ初期化子》を含む。)
―
デストラクタ
―
コンストラクタ 又は デストラクタから( 直接 又は 間接に )呼び出される関数
の演算対象が,構築中 又は 解体中のオブジェクトを参照していて,その演算対象の静的型がコンストラクタ
又は デストラクタのクラスでもなく,その基底クラスでもない場合,その
の結果は未定義とする。
(
#)
)を,構築中 又は 解体中に使うことができる(
(
参照)
。
が次のいずれ
かの中で使われて,その演算対象が構築中 又は 解体中のオブジェクトを参照している場合,そのオブジェクトは,コ
ンストラクタ 又は デストラクタのクラスを型とする最派生オブジェクトとみなされる。
―
コンストラクタ(データメンバの《メンバ初期化子》を含む。)
―
デストラクタ
―
コンストラクタ 又は デストラクタから( 直接 又は 間接に )呼び出される関数
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
((
の演算対象が構築中 又は 解体中のオブジェクトを参照していて,その演算対象の静的型が,コンスト
ラクタ 又は デストラクタの,それ自身のクラス 又は その基底クラスに対する,ポインタ 又は オブジェクトではな
い場合,その
の結果は未定義とする。
例
H
Q
3
&
R&
6
3
H
Q
R&
"
3
H
Q
3
"H!
6! &
R&
#
3
6
"
Q
3
#
3
"6!
Q
R
R&
"33"H!
6!
Q
! &
''
"
の
P
! &
''
適格
3
!
の型
H
は
"
の基底クラスとなり,
''
"
の
P
ができる。
! &
''
未定義動作
3
型
6
は
"
の基底クラスでない
V"!
&
''
適格
3
の型は
H!
で,
H
が
"
の基底クラス
''
故に
"!
となる。
P"!
&
''
未定義動作
3
の型は
6!
で
R
''
6
が
"
の基底クラスでないから
クラスオブジェクト のコピー
クラスオブジェクトは,次の二つの方法でコピーすることができる。
―
関数の実引数渡し(
#
) 及び 関数の値の返却(
((
)を含む初期化(
及び
#
参照)
―
代入(
#)
)
概念的には,これらの二つの操作は,コピーコンストラクタ(
) 及び コピー代入演算子(
#
)で実現される。
クラス
5
のテンプレートでないコンストラクタは,次の条件をすべて満たす場合,コピーコンストラクタとする
。
―
その第
仮引数の型が,
50
,
50
,
50
又は
50
のいずれかである。
―
仮引数が他にないか,あってもすべてが省略時実引数(
(
)をもつ。
例
5335
50
及び
533550
%L
は,コピーコンストラクタとなる。
5
Q
''
(((
3
5 &
5
50
%
L &
R&
5
L &
''
5
を呼び出す。
5
. &
''
5
50
を呼び出す。
5
%
&
''
5
50
を呼び出す。
参考
クラスに対して,すべての形式のコピーコンストラクタを宣言してもよい。
例
5
Q
''
(((
3
5
50 &
550 &
''
B>
R&
注
テンプレートコンストラクタは,コピーコンストラクタではないので,そのテンプレートは,コピーコンストラクタの暗黙の宣言を抑
止しない。テンプレートコンストラクタは,コピーコンストラクタも含めて,他のコンストラクタとともに,多重定義解決に参加する。
そして,テンプレートコンストラクタは,それが他のコンストラクタよりもよく合致する場合,オブジェクトのコピーに使われることが
ある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
()
参考
クラス
5
が,型
50
を仮引数とするコピーコンストラクタしかもたない場合,型
5
又は 型
5
の初期化子は,型
5
のオブジェクト(
0
修飾付きの場合も含む。)を初期化することができない。
例
5
Q
5 &
''
省略時コンストラクタ
550 &
''
ではない仮引数をもつコピー
''
コンストラクタ
R&
5
&
5
%&
''
エラー
3
533550
は,
を
にコピー
''
することができない。
クラス
5
のコンストラクタの宣言は,その第
仮引数が型
5
(
0
修飾付きの場合も含む。)であって,他に実引数
がないか,あっても他のすべてが省略時の実引数をもつ場合,不適格とする。クラスオブジェクトをそのクラス型の
オブジェクトにコピーするのにメンバ関数テンプレートを具現することはない。
例
F
Q
F &
R&
F
&
Q
F
&
''
メンバテンプレートを具現しない。
R
クラスの定義がコピーコンストラクタを明示的に宣言しない場合,コピーコンストラクタが暗黙に宣言される。し
たがって,次のクラス定義に対してはコピーコンストラクタが暗黙に宣言される。
5
Q
5
50
&
R&
その後で,利用者宣言のコンストラクタが,次のように定義された場合,
5
のコピーコンストラクタをどのように用
いても,あいまいとなるため不適格とする。
5335
50
%.
Q
'!
(((
!'
R
診断メッセージは,必要としない。
次の条件をすべて満たす場合,クラス
5
に対して暗黙に宣言されるコピーコンストラクタは,次の形式とする。
5335
50
―
5
の直接 又は 仮想の基底クラス
"
のそれぞれが,
"0
又は
"0
を第
仮引数の型
とするコピーコンストラクタをもつ。
―
5
のすべてのクラス型
@
( 又は その配列型)の非静的データメンバについて,それらのクラス型が,
@0
又は
@0
を第
仮引数の型とするコピーコンストラクタをもつ
。
そうでない場合,暗黙に宣言されるコピーコンストラクタは,次の形式とする。
533550
暗黙に宣言されたコピーコンストラクタは,クラスの
メンバとなる。
クラス
5
のコピーコンストラクタは,それが暗黙に宣言され,次の条件がすべて成り立つ場合,自明であるという。
―
クラス
5
が,仮想関数(
)をもたず,仮想基底クラス(
)ももたない。
―
5
の直接基底クラスのそれぞれが,自明なコピーコンストラクタをもつ。
―
5
のすべてのクラス型( 又は その配列型)の非静的データメンバについて,それぞれのクラス型が自明な
コピーコンストラクタをもつ。
そうでない場合,コピーコンストラクタは,自明でないという。
暗黙に宣言されたコピーコンストラクタは,そのクラス型のオブジェクトのコピー 又は そのクラス型の派生クラ
ス型のオブジェクトのコピーによって,そのクラス型のオブジェクトが初期化されるとき,暗黙に定義される
。
注
このことは,暗黙に宣言されたコピーコンストラクタの参照仮引数は,
付きの左辺値に結合することができないことを意味
する(
参照)
。
注
直接初期化 及び コピー初期化の詳細は,
で規定する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
参考
コピーコンストラクタは,処理系がそれを用いることを省く場合(
)であっても,暗黙に定義さ
れる。
コピーコンストラクタが暗黙に定義されているクラスが,次のいずれかをもつ場合,そのプログラムは不適格とする。
―
アクセスできないコピーコンストラクタ 又は あいまいなコピーコンストラクタをもつクラス型( 又は そ
の配列型)の非静的データメンバ
―
アクセスできないコピーコンストラクタ 又は あいまいなコピーコンストラクタをもつ基底クラス
クラスの暗黙に宣言されたコピーコンストラクタが暗黙に定義される前に,そのクラスの,直接基底クラス,仮想基
底クラス 及び 非静的データメンバに対して暗黙に宣言されたコピーコンストラクタのすべてが,暗黙に定義されて
いなければならない。
参考
暗黙に宣言されたコピーコンストラクタは,例外仕様(
#
)をもつ。
クラス
5
に対して暗黙に定義されたコピーコンストラクタは,その部分オブジェクトをメンバごとにコピーする。
コピーの順序は,利用者定義コンストラクタ内の基底クラス 及び メンバを初期化する順序(
(
)と同じとする。
それぞれの部分オブジェクトは,その型に応じて次に示す方法でコピーが行われる。
―
部分オブジェクトがクラス型の場合,そのクラスのコピーコンストラクタが使われる。
―
部分オブジェクトが配列の場合,要素の型ごとに適切な方法で,各要素のコピーが行われる。
―
部分オブジェクトがスカラ型の場合,組込みの代入演算子が使われる。
仮想基底クラス型の部分オブジェクトは,暗黙に定義されたコピーコンストラクタによって,
回だけコピーが行わ
れなければならない(
(
参照)
。
利用者宣言されたコピー代入演算子
533%
は,
5
の非静的かつ非テンプレートの,
個の仮引数をもつメ
ンバ関数とし,その仮引数の型は,
5
,
50
,
50
,
50
,
50
のいずれかとする
。
参考
多重定義される代入演算子は,仮引数を一つだけもつと宣言しなければならない(
#
参照)
。
参考
クラスに対して,複数の形式のコピー代入演算子を宣言してもよい。
参考
クラス
5
が,
50
を仮引数とするコピー代入演算子しかもたない場合,型
5
の式は,型
5
のオブ
ジェクトに代入することができない。
例
Q
5 &
50
%50 &
R&
5
&
5
&
Q
%
&
''
エラー
3
''
533%50
は,
を
に代入する
''
ことができない。
R
クラスの定義がコピー代入演算子を明示的に宣言していない場合,コピー代入演算子が暗黙に宣言される。次の条
件をすべて満たす場合,クラス
5
に対して暗黙に宣言されたコピー代入演算子は,次の形式とする。
50
533%
50
―
5
の直接基底クラス
"
のそれぞれが,
"0
,
"
又は
"
を仮引数の型とするコピー代
入演算子をもつ。
―
5
のすべてのクラス型
@
( 又は その配列型)の非静的データメンバについて,それらのクラス型が,
@0
,
@0
又は
@
を仮引数の型とするコピー代入演算子をもつ
。
そうでない場合,暗黙に宣言されたコピー代入演算子は,次の形式とする。
50
533%50
クラス
5
に対して暗黙に宣言されたコピー代入演算子の返却値の型は,
50
とする。それは,代入演算子を呼び出
したオブジェクト,すなわち,代入先のオブジェクトを返却する。暗黙に宣言されたコピー代入演算子は,そのクラ
注
テンプレート代入演算子は,コピー代入演算子ではないので,そのテンプレートは,コピー代入演算子の暗黙の宣言を抑止しない。テ
ンプレート代入演算子は,コピー代入演算子も含めて,他の代入演算子とともに,多重定義解決に参加する。そして,テンプレート代入
演算子は,それが他の代入演算子よりもよく合致する場合,オブジェクトの代入に使われる。
注
このことは,暗黙に宣言されたコピー代入演算子の参照仮引数は,
付きの左辺値と結合することができないことを意味する
(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(*
スの
メンバとなる。クラスに対してコピー代入演算子が利用者宣言されない場合には暗黙に宣言が
なされるので,基底クラスのコピー代入演算子(
#
)は,派生クラスのコピー代入演算子によって常に隠ぺいさ
れる。
《
!
宣言》
(
)
)は,派生クラスに対するコピー代入演算子と同じ仮引数の型をもつコピー代入演算子を,
基底クラスから取り込むが,それは,コピー代入演算子の明示的な宣言とはみなされず,派生クラスのコピー代入演
算子の暗黙の宣言を抑止しない。この《
!
宣言》によって導入された演算子は,派生クラスにおいては,暗黙に
宣言されるコピー代入演算子によって隠ぺいされる。
クラス
5
のコピー代入演算子は,それが暗黙に宣言され,次の条件がすべて成り立つ場合,自明であるという。
―
クラス
5
が仮想関数(
)をもたず,仮想基底クラス(
)ももたない。
―
5
(
)の直接基底クラスのそれぞれが,自明なコピー代入演算子をもつ。
―
5
のすべてのクラス型( 又は その配列型)の非静的データメンバについて,それぞれのクラス型が自明な
コピー代入演算子をもつ。
そうでない場合,コピー代入演算子は,自明でないという。
暗黙に宣言されたコピー代入演算子は,そのクラス型のオブジェクトに,そのクラス型の値 又は そのクラス型の
派生クラスの型の値が代入されるとき,暗黙に定義される。コピー代入演算子が暗黙に定義されているクラスが,次
のいずれかをもつ場合,そのプログラムは不適格とする。
―
定値型の非静的データメンバ
―
参照型の非静的データメンバ
―
アクセスできないコピー代入演算子をもつクラス型( 又は その配列型)の非静的データメンバ
―
アクセスできないコピー代入演算子をもつ基底クラス
クラスの暗黙に宣言されたコピー代入演算子が暗黙に定義される前に,その直接基底クラス 及び 非静的データメン
バに対して暗黙に宣言されたコピー代入演算子すべてが,暗黙に定義されていなければならない。
参考
暗黙に宣言されたコピー代入演算子は,例外仕様(
#
)をもつ。
クラス
5
に対して暗黙に定義されたコピー代入演算子は,その部分オブジェクトのメンバごとの代入を行う。まず
5
の直接基底クラス群に対する代入が《基底指定子並び》の宣言順に実施され,次に,
5
の直下の非静的データメン
バに対する代入がクラス定義に宣言された順に実施される。それぞれの部分オブジェクトは,その型に応じて次に示
す方法で代入される。
―
部分オブジェクトがクラス型の場合,そのクラスのコピー代入演算子が使われる( 明示的な修飾が用いら
れたかのように行われる。すなわち,より派生したクラスに仮想上書き関数があっても無視される。)
。
―
部分オブジェクトが配列の場合,要素の型ごとに適切な方法で,各要素の代入が行われる。
―
部分オブジェクトがスカラ型の場合,組込みの代入演算子が使われる。
仮想基底クラス型の部分オブジェクトに対して,暗黙に定義されたコピー代入演算子によって代入が複数回行われる
否かは,未規定とする。
例
H
Q
R&
6
3
H
Q
R&
"
3
H
Q
R&
7
3
"
6
Q
R&
ここで,仮想基底クラス
H
の部分オブジェクトに対する代入が,
7
に対する暗黙に定義されたコピー代
入演算子によって
度行われるか否かは,未規定とする。
あるオブジェクトのコピー代入演算子 又は コピーコンストラクタが暗黙に使われ,その特殊メンバ関数がアクセ
スできない(
)場合,そのプログラムは不適格とする。
参考
コピーコンストラクタ 又は コピー代入演算子を使ってオブジェクトを別のオブジェクトにコピーする
ことで,それらのオブジェクトの配置や大きさが変わることはない。
処理系は,ある基準が満たされれば,そのクラスオブジェクトのコピーによる構築を省略してよい。これは,このオ
ブジェクトのコピーコンストラクタ 及び/又は デストラクタが副作用をもつ場合も含む。コピーによる構築を省略す
る場合,処理系は,省略されたコピー演算のコピー元とコピー先を,同一オブジェクトに対する二つの異なる参照と
して扱い,この最適化を施さなかった場合に二つのオブジェクトが解体される時点の遅いほうで,そのオブジェクト
を解体する
。次の状況で,コピー演算の省略は許される。
( 複数のコピーの省略が組み合わされることもある。)
注
解体されるオブジェクトは二つではなく一つであり,コピーコンストラクタ一つを実行しなかったのだから,一つのオブジェクトの構
築に対して,なおちょうど 一つの解体が行われることになっている。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
―
返却値の型がクラスである関数の
文の式が,関数の返却値の型と同じ
0
修飾なしの型の
0
でない自動記憶域期間のオブジェクトの名前の場合,自動記憶域期間のオブジェクトを直接関数の返却値
として構築することで,コピー演算は省略できる。
―
参照に結合されていない一時クラスオブジェクトがそれと同じ
0
修飾なしの型をもつクラスオブジェクト
にコピーされる場合,一時オブジェクトを直接そのコピー先に構築することで,コピー演算は省略できる。
例
Q
3
&
X &
0 &
R&
Q
&
&
R
+
%
&
この例に省略の基準を組み合わせて使うことで,次に示すクラス
のコンストラクタの
度の呼出
しを取り除くことができる。
―
局所的な自動記憶域期間のオブジェクト
から関数
の返却値となる一時オブジェクトへの
コピー
―
その一時オブジェクトからオブジェクト
+
へのコピー
つまり,局所オブジェクト
の構築を,大域オブジェクト
+
の直接の初期化とする。このオブジェクト
の解体は,プログラムの終了時に行われる。
多重定義
同じ名前を指定した異なる宣言が同一有効範囲内に複数ある場合,その名前は,多重定義されている
という。更に,同一有効範囲内に二つの宣言が同じ名前を宣言していて,その型が異なる場合,それらを多重定義宣
言と呼ぶ。関数宣言だけが多重定義することができ,オブジェクト 及び 型の宣言は,多重定義することができない。
多重定義関数名を呼出しに使う場合,どの多重定義関数宣言を参照するかは,それを使う位置から見える多重定義
宣言の仮引数の型と使用位置の実引数の型とを比較することによって決まる。この関数を選択する処理を多重定義解
決と呼び,
で規定する。
例
&
&
L &
''
を呼び出す。
L(. &
''
を呼び出す。
多重定義可能な宣言
すべての関数宣言が多重定義可能とは限らない。多重定義することができない関数宣言
をここで規定する。同一有効範囲内に多重定義ができない宣言が複数あった場合,そのプログラムは不適格とする。
参考
この制約は,次の場合に適用される。
―
一つの有効範囲内にある複数の明示的宣言に対して
―
明示的宣言と《
!
宣言》
(
)
)による宣言の組合せに対して
この制約は,
( 例えば《
!
指令》による)名前検索 又は ( 例えば演算子関数に対する)多重定義解決の
結果として集められた関数群に対しては,適用されない。
次の関数宣言は,多重定義することができない。
―
返却値の型だけが異なる関数宣言は,多重定義することができない。
―
同じ名前 及び 同じ仮引数型をもつ複数のメンバ関数宣言であって,そのいずれかが静的メンバ関数宣言
(
*
)の場合,多重定義することができない。同様に,同じ名前,同じ仮引数型 及び 同じテンプレート
仮引数並びをもつ複数のメンバ関数テンプレート宣言は,そのいずれかが静的メンバ関数テンプレート宣
言の場合,多重定義することができない。多重定義解決(
)のためにメンバ関数に対して作られる
暗黙のオブジェクト仮引数の型は,この規則を適用するための仮引数型を比較するときには,比較しない。
一方,同じ名前 及び 同じ仮引数型をもつメンバ関数宣言群の中に静的メンバ関数宣言がない場合,暗黙
のオブジェクト仮引数の型が異なれば,それらのメンバ関数宣言は,多重定義することができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
例
その違いを次に示す。
5
Q
&
&
''
不適格
&
''
不適格
&
''
不適格
&
&
''
B>3
は静的でない。
&
''
B>3
は静的でない。
R&
参考
#
で規定するとおり,同等な仮引数宣言をもつ関数宣言は,同じ関数宣言なので,多重定義するこ
とができない。
―
同等な型定義の型を使っていることを除いて違いのない二つの仮引数宣言は,互いに同等とす
る。
で定義された型は,別個の型ではなく,対象とした型の同義語となるに過ぎない
(
)
参照)
。
例
<&
&
<
&
''
B>3
の再宣言
Q
'!
(((
!'
R
<
Q
'!
(((
!'
R
''
エラー
3
の再定義
一方,列挙体は,それぞれ別個の型であり,多重定義関数宣言の区別に使用することができる。
例
8
Q
R&
Q
'!
(((
!'
R
8
Q
'!
(((
!'
R
''
B>
―
ポインタ
!
と配列
ST
の違いしかない仮引数宣言は,互いに同等とする。つまり,配列宣言は,
調整されてポインタ宣言となる(
#
参照)
。配列の次元は,第
次元以降だけが仮引数の型
として区別される(
参照)
。
例
! &
ST &
''
!
と同じ
S,T &
''
!
と同じ
SOT &
''
!
と同じ
! SL.T &
S/TSL.T &
''
! SL.T
と同じ
S,TSL.T &
''
! SL.T
と同じ
! S+.T &
''
! SL.T
とは異なる
―
仮引数の宣言であって一方が関数型であり他方がその同じ関数型へのポインタである場合,そ
の仮引数は互いに同等とする。つまり,関数型は,関数型へのポインタに調整される(
#
参照)
。
例
&
! &
''
の再定義
Q
R
''
の定義
!
Q
R
''
不適格。
の再定義
―
及び/又は
の違いしかない仮引数宣言は,互いに同等とする。つまり,各仮
引数の型指定子
及び
は,宣言,定義 又は 呼出しの対象となる関数がどれか
を決めるときには無視される。
例
<&
&
&
''
の再宣言
Q
'!
(((
!'
R
''
の定義
<
Q
'!
(((
!'
R
''
エラー
3
の再定義
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
仮引数型指定子の最も外側のレベルにある型指定子
及び
だけが無視され,仮
引数型指定子の中に埋め込まれた型指定子
及び
の有無は,多重定義された関
数宣言の区別に使われる
。特に,任意の型
に対して
:
へのポインタ
;
,
:
へ
のポインタ
;
及び
:
へのポインタ
;
は,異なる仮引数型とみなす。
:
への参照
;
,
:
への参照
;
及び
:
への 参照
;
も,異なる仮引数型とみなす。
―
二つの仮引数宣言の省略時実引数だけが異なる場合は,同等とする。
例
&
%
OO &
''
B>3
の再宣言
%
NN
&
''
B>3
の再宣言
&
''
B>3
の多重定義宣言
Q
L
+ &
''
B>3
を呼び出す。
L &
''
B>3
を呼び出す。
&
''
エラー
3
なのか
''
なのかが不明。
R
宣言の合致
二つの同じ 名前の関数宣言は,同じ 有効範囲内にあり,同等の仮引数宣言(
)である場合,
同じ関数を参照する。派生クラスの関数メンバは,基底クラス内の同じ名前の関数メンバと同じ有効範囲にはない。
例
"
Q
3
&
R&
#
3
"
Q
3
! &
R&
ここで,
#33!
は,
"33
を隠ぺいし ,多重定義とならない。
#!
Q
VL &
''
エラー
3
''
#33!
が
"33
を隠ぺいしている。
V"33L &
''
B>
VY"Y &
''
B>3
#33
を呼び出す。
R
局所的に宣言された関数は,それを取り囲む有効範囲内の関数と同じ有効範囲にはない。
例
! &
Q
&
YY &
''
エラー
3
が
!
を隠ぺいしているので,
''
その有効範囲に
!
はない。
R
Q
&
Q
&
''
を隠ぺい
NN
OO &
''
エラー
3
その有効範囲には
R
''
しかない。
R
多重定義されたメンバ関数のそれぞれは,互いに異なるアクセス規則をもつことができる。
注
仮引数型に関数型がある場合,例えば,関数へのポインタ型の仮引数の場合,内側の関数型を指定する仮引数型の最も外側のレベルに
ある型指定子
及び
は,無視される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
例
Q
3
!
&
$&
3
!
Q
$
%
&
%
&
R
''
(((
3
Q
%
S$
%
T&
R
''
(((
R&
多重定義解決
呼出しの実引数となる一連の式 及び その呼出しの文脈で呼び出され うる候補関数の集合が与
えられた場合に,呼び出すべき最良の関数を選択する機構を,多重定義解決と呼ぶ。次の基準によって,最良の関数
を選択する。
―
実引数の個数
―
実引数型と候補関数の仮引数型との合致の度合い
―
( 非静的メンバ関数については )オブジェクトと暗黙のオブジェクト仮引数との合致の度合い
―
候補関数のその他の特性
参考
多重定義解決によって選択された関数が,文脈に対して適切であることが保証されるわけではない。関
数のアクセス可能性などの他の制約によって,その呼出し位置の文脈によってはその関数の使用が不適格
となることがある。
この言語規格では,多重定義解決は,次の七つの異なる文脈で,呼び出すべき関数の選択が行われる。
―
関数呼出しの構文で名前のある関数の呼出し(
)
―
関数呼出しの構文で名前のあるクラスオブジェクトに対する,関数呼出し演算子の呼出し ,ポインタから
関数への変換関数の呼出し ,参照からポインタを経ての関数への変換関数の呼出し 又は 参照から関数へ
の変換関数の呼出し(
)
―
式中で参照される演算子の呼出し(
)
―
クラスオブジェクトの直接の初期化(
#
)を行うコンストラクタの呼出し(
)
―
クラスオブジェクトのコピーによる初期化(
#
)を行う利用者定義変換の呼出し(
)
―
クラス型の式から非クラス型のオブジェクトを初期化する場合の変換関数の呼出し(
#
)
―
参照が直接結合される左辺値に変換する場合の変換関数の呼出し(
(
)
これらの文脈ごとに一意な方法で候補関数の集合 及び 一連の実引数が定義されるが,候補関数の集合 及び 一連の
実引数が決まった後は,最良の関数の選択方法は,いずれの場合にも同じになる。その方法は,次のとおりとする。
―
まず,候補関数の部分集合として,実引数の個数が適切であって,その他の条件を満たす関数を選択し ,
二次候補関数(
)の集合を作る。
―
次に,各実引数を,それぞれの二次候補関数の対応する仮引数と合致させるために必要な暗黙変換手順
(
)に基づいて,最良の二次候補関数を選択する。
最良の二次候補関数が唯一見つかった場合,多重定義解決が成功したことになり,その関数を結果とする。そうで
ない場合,多重定義解決は失敗したことになり,その呼出しは,不適格とする。多重定義解決が成功したが,使用さ
れた文脈で最良の二次候補関数がアクセスできない(
)場合,そのプログラムは不適格とする。
候補関数 及び 実引数並び
ここでは,多重定義解決が使われる七つの文脈ごとに,多重定義解決に渡され
る候補関数の集合 及び 実引数並びを規定する。ここで定義するソースプログラム上の変形 及び 生成は,多重定義解
決の手順の説明だけを目的としている。処理系がそのとおりの変形 及び 生成を行う必要はない。
同じ実引数並びに対する多重定義解決用の候補関数の集合に,メンバ関数 及び 非メンバ関数の両方が混在しても
よい。その混在した集合の中で実引数並びと仮引数並びを比較可能にするために,メンバ関数は,暗黙のオブジェク
ト仮引数と呼ぶ仮引数を一つ付加的にもつと考える。暗黙のオブジェクト仮引数は,メンバ関数を呼び出す対象とな
るオブジェクトを表現する。多重定義解決のために,メンバ関数は,静的であっても非静的であってもその暗黙のオ
ブジェクト仮引数をもつが,コンストラクタはもたない。
同じように,必要に応じて,関数が作用するオブジェクトを示す暗黙のオブジェクト実引数を含めて実引数並びを
作る場合がある。実引数も仮引数もそれぞれの並びの中での位置が意味をもつから,暗黙のオブジェクト仮引数が存
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
在する場合,それを先頭の仮引数とし ,暗黙のオブジェクト実引数が存在する場合,それを先頭の実引数とする。
非静的メンバ関数では,暗黙のオブジェクト仮引数の型は,
:
5
への参照
;
とする。ここで,
5
は,その関数が メ
ンバとなっているクラスとし ,
は,そのメンバ関数宣言の
0
修飾とする。
例
クラス
5
の定値のメンバ関数では,その追加された仮引数は,
:
5
への参照
;
という型をもつと考
える。
変換関数の場合,その関数を暗黙のオブジェクト実引数のクラスのメンバとみなして,暗黙のオブジェクト仮引数の
型を定める。
《
!
宣言》によって派生クラスに導入された非変換関数の場合,その関数を,その派生クラスのメン
バとみなして,暗黙のオブジェクト仮引数の型を定める。静的メンバ関数の場合,
(その関数が選択されても,暗黙の
仮引数オブジェクトは使われずに廃棄されるので )暗黙のオブジェクト仮引数は,任意のオブジェクトと合致すると
考える。
参考
静的メンバ関数の暗黙のオブジェクト仮引数に対しては,実際の型を作らず,その仮引数に対する変換
手順を決めることもしない(
参照)
。
多重定義解決の間,暗黙のオブジェクト実引数は,他の実引数と区別しない。しかし,暗黙のオブジェクト仮引数
は,次に示す追加規則に従って対応する実引数からの変換が行われるという点で,他と異なる。
―
暗黙のオブジェクト仮引数に対する実引数を保持するために,一時オブジェクトを導入することはない。
―
型を合致させるために,利用者定義変換を適用することはない。
―
たとえ暗黙のオブジェクト仮引数に
!
修飾がない場合であっても,右辺値の一時変数が,その他のす
べての基準で暗黙のオブジェクト仮引数の型に変換することができる場合には,その一時変数を仮引数に
結合することができる。
暗黙の変換手順では,一つの利用者定義変換しか使えないので,特別な規則を適用して最良の利用者定義変換を選
択する(
及び
参照)
。
例
Q
3
&
''
(((
R&
7
3
Q
3
7 &
''
(((
R&
%
L&
''
不適格
3
7L
は試されない。
候補が関数テンプレートの場合には,テンプレート実引数の導出(
及び
参照)によって,
( 複数の )
候補の関数テンプレート特殊化を生成する。これらの候補は,候補関数として通常の方法で処理する
。一つの名
前によって,一つ以上の関数テンプレートを参照し ,同時に多重定義の非テンプレートの関数群を参照することがで
きる。その場合,各関数テンプレートから生成された一群の候補関数を,非テンプレートの候補関数の集合に加える。
関数呼出し構文
関数呼出しは,任意の深さの括弧付きで入れ子になった《後置式》の後に,省略可能の
《式並び》を括弧で囲った次の形式をとる(
#
参照)
。
E
E
E
《後置式》
E
E
E
《式並び》
《後置式》が,関数,関数テンプレート(
##
),クラス型のオブジェクト 又は 関数へのポインタの集合のいずれ
かの名前である場合には,多重定義解決が必要となる。
で,
《後置式》が関数名 及び 関数テンプレート名の場合に呼び出すべき関数を決めるための多重定義解
決の方法を規定し,
で,
《後置式》がクラス型のオブジェクトの名前の場合に呼び出すべき関数を決めるた
めの多重定義解決の方法を規定する。
第
の場合は,
《後置式》が
09
という形であって,
9
が多重定義関数群の集合を名指しているときに生じる。関数呼
出しの構文では,
9
が名指している関数の集合には,非メンバ関数 及び 静的メンバ関数だけが含まれる
。その文
脈では,
09
を使った場合の挙動は,
9
という名前自体を使った場合と同じとする。したがって,
09
《式並び》
注
実引数導出の手順が,テンプレート関数群の仮引数の型を完全に決定する。つまり,関数テンプレート特殊化の仮引数は,テンプレー
ト仮引数の型を含まない。したがって,その関数テンプレート特殊化は,多重定義解決の以降の過程で,通常の(非テンプレートの)関
数として扱うことができる。
注
5
が非静的メンバ関数の名前の場合,
'5
はメンバへのポインタとなり,関数呼出し構文には使えない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)#
は,単に
9
《式並び》
となる。これについては,
で規定する。他の文脈での
09
の解決は,
で
規定する。
名指された関数の呼出し
ここでは,
《後置式》の中に呼び出され うる一つ以上の関数を指す名前を含む
形の関数呼出しだけを対象とする。その《後置式》は,括弧付きで任意の深さの入れ子になってもよいが,次の形式
のいずれかとする。
後置式
3
後置式
(
識別子式
後置式
V
識別子式
一次式
これらは,構文としての,修飾付きの関数呼出し 及び 修飾なしの関数呼出しを表現している。
修飾付き関数呼出しの場合,演算子
V
又は
(
の後に位置する《識別子式》が解決すべき名前となる。
6V"
とい
う構文は,
!6 ("
という構文と同等なので,この箇条の残りの部分では,一般性を失うことなく,すべてのメンバ
関数呼出しを,オブジェクト 及び 演算子
(
を使った形式を標準として扱う。更に,この箇条では,
をクラスとし
て,演算子の左演算対象にあたる《後置式》が,型
:
;
をもつと仮定する
。この仮定の下に,クラス内の名
前検索規則(
)に従って,
のメンバ関数として,関数呼出し内の《識別子式》を検索する。メンバ関数が見つ
かった場合は,その関数 及び その( 複数の)多重定義宣言で候補関数の集合を構成する。その実引数並びは,その
呼出しにある《式並び》の先頭に暗黙のオブジェクト実引数(
)を付加した並びとする。このとき,暗黙のオ
ブジェクト実引数としては,正規化されたメンバ関数呼出しでの演算子
(
の左演算対象をあてる。
修飾なし関数呼出しの場合,名前は,演算子
V
又は
(
で修飾されることはなく,より一般的な《一次式》の形式
とする。関数呼出しの文脈において,関数呼出し 内の名前検索の通常規則(
)に従って,名前検索を行う。名
前が非メンバ関数宣言として解決した場合,その関数 及び その( 複数の )多重定義宣言が候補関数の集合を構成す
る
。その実引数並びは,呼出し内の《式並び》とする。名前が非静的メンバ関数として解決した場合,関数呼出
しは,実際にはメンバ関数呼出しとなる。キーワード
(
*
)が有効範囲内にあり,かつ,そのメンバ関数の
クラス 又は その派生クラスを参照している場合,関数呼出しは,
!
を演算子
(
の左側の《後置式》に使った
正規化された修飾付き関数呼出しに変形する。その候補関数 及び 実引数並びは,前の箇条の修飾付き関数呼出しの
場合と同じとする。キーワード
が有効範囲内にない場合 又は 別のクラスを参照している場合,名前解決で,あ
るクラス
の静的メンバが見つかったことになる。その場合には,
内にあるその関数名のすべての多重定義宣言を
候補関数とし ,型
のオブジェクトを暗黙のオブジェクト実引数とする
。しかし ,その場合に,多重定義解決
が
の非静的メンバ関数を選択したなら,その呼出しは不適格とする。
クラス型オブジェクト の呼出し
関数呼出し構文としての《一次式》
8
を評価した結果,型
:
;
のク
ラスオブジェクトとなる場合,その候補関数の集合には,少なくとも
の( 複数の)関数呼出し演算子すべてを含め
る。
の関数呼出し演算子は,
8 (
という文脈内での
という名前を通常に検索して得る。
更に,
内に宣言された上の形式の変換関数のそれぞれに対して,その代理呼出し関数を候補関数に加える。
《変換型識別子》
《
修飾子》
&
変換関数が上に示した形であったとき,候補に加える代理呼出し関数は,次に示す形とする。
E
《変換型識別子》
9
CL
L
…
C
9
L
…
&
ここで,
《
0
修飾子》は
に対する
0
修飾と同じかそれ以上の
0
修飾とし,
《変換型識別子》は型
:
仮引数が
CL C+
…
C
で
E
を返す関数へのポインタ
;
,
:
仮引数が
CL C+
…
C
で
E
を返す関数へのポインタの参照
;
又は
:
仮引
数が
CL C+
…
C
で
E
を返す関数の参照
;
を表すとする。また,
は他に現れていない一意な名前とす
る。同様に,アクセス可能な基底クラスで宣言された変換関数のそれぞれについて,それが他の介在する宣言によっ
て
内で隠ぺいされていないときには,候補関数の集合に,その変換関数に対する代理呼出し関数を加える
。
多重定義解決によって代理呼出し関数が選択された場合,上で定義したとおりの関数本体を実行する。すなわち,
8
を適切な関数に変換し ,元の呼出しの実引数を使ってその関数を呼び出す。
注
オブジェクトの型に付けた
"#
修飾子は,左辺値 及び クラスの右辺値オブジエクトの両方に対する多重定義解決において意味をもつ。
注
通常の名前隠ぺい規則によって,それらは,同一ブロック 又は 名前空間有効範囲で見つかるすべての宣言 又は 《
指令》によっ
て導入されたものとなる。
注
多重定義解決の間,メンバ関数を特徴付ける暗黙のオブジェクト仮引数に対応させるために,暗黙のオブジェクト実引数が実引数並び
に追加されるが,選択された関数の呼出しには使われない。メンバ関数はすべて,同じ暗黙のオブジェクト仮引数をもつので,その暗黙
のオブジェクト自体は,関数の選択 及び 棄却に使われることはない。
注
この生成によって,多重定義解決では他と区別することができない候補関数を作り出すことがある。宣言が互いに同等であったり,そ
の返却値の型が異っているだけであったりする候補関数が作り出されうるからである。多重定義解決が,この区別することができない関
数よりもその呼出しによく一致するものを選択することができなかった場合,その呼出しはあいまいとなる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)(
多重定義解決に供される実引数並びは,関数呼出し構文内の実引数の式の前に,暗黙のオブジェクト実引数
8
を
付け加えた並びとする。
参考
元の呼出しと関数呼出し演算子とを比較する場合,暗黙のオブジェクト実引数は,関数呼出し演算子の
暗黙のオブジェクト仮引数と比較される。元の呼出しと代理呼出し関数とを比較する場合は,暗黙のオブ
ジェクト実引数は,代理呼出し関数の第
仮引数と比較される。代理呼出し関数を生成する元となった変
換関数が,その仮引数に対する変換手順に使われる。なぜなら,その変換関数が,暗黙のオブジェクト実
引数を第
仮引数の要求する適切な関数ポインタ 又は 関数参照に変換するからである。
例
L &
+ &
!L &
!+ &
6
Q
L
Q
L&
R
+
Q
+&
R
R
&
%
L &
''
変換関数から返されるポインタを
''
介して,
L
を呼び出す。
式中の演算子
式中の演算子のどの演算対象もクラス型でも列挙型でもない場合,その演算子は,組込み
演算子とみなし ,
#
に従って解釈する。
参考
(
,
(!
及び
33
は,多重定義されないので,それらの演算子は,常に組込み演算子となり,
#
に従って
解釈する。
23
は,多重定義されないが,第
又は 第
の演算対象がクラス型 又は 列挙型である場合に
は,この箇条の規則を用いて,第
及び 第
の演算対象に適用する変換を決める(
#(
参照)
。
例
F
Q
3
F
F0 &
F
! &
!
&
R&
F
)
F0
F0 &
Q
!
%
YY
)
YY&
''
両演算対象とも利用者定義型で
''
ないため不適格となる。
<
%
L
)
L&
''
その演算を実行する利用者定義型
''
が存在する場合でも
''
常に
+
と評価される。
R
ど ちらかの演算対象の型がクラス型 又は 列挙型である場合,その演算を実装する利用者定義演算子関数が宣言さ
れているかもしれないし,演算対象を組込み演算子に適した型に変換する利用者定義変換が必要となるかもしれない。
この場合,多重定義解決を使って,その演算子を実装するのに演算子関数と組込み演算子のど ちらを呼び出すべきか
を決める。そのため,まず演算子記法を同等の関数呼出し記法に変形する。それを
表
にまとめて示す(ここで
]
は,
それぞれの箇条で定める演算子とする。)
。
表
演算子と関数呼出し記法の関係
箇条
式
メンバ関数
非メンバ関数
#
N
(N
N
#
N
(N
N
#
%
(%
##
ST
(ST
#(
V
(V
#)
N
(N
.
N
.
単項演算子
N
の演算対象の
0
修飾なしの型が
の場合 又は ,
項演算子
N
の左演算対象の
0
修飾なしの型が
で,右演算対象の
0
修飾なしの型が
の場合,それらの演算子に対して,メンバ候補関数集合,非メンバ候補
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
))
関数集合 及び 組込み候補関数集合の三つの集合を,次のとおり構成する。
―
がクラス型の場合,メンバ候補は,
N
の修飾付き検索(
)の結果とする。そ
うでない場合,メンバ候補の集合は,空とする。
―
非メンバ候補の集合は,すべてのメンバ関数が無視されることを除いて,修飾なし関数呼出しの通常の名
前検索規則(
)に従って,
N
の式内の文脈で修飾なし検索をした結果とする。
―
演算子
,単項演算子
0
又は 演算子
V
に対しては,組込み候補の集合は空とする。その他の演算子に対
しては,
(
で規定されるすべての候補演算子関数のうち,元の演算子と比較して次の条件がすべて成り
立つものを,組込み候補とする。
同一の演算子名をもつ。
演算対象の個数が等しい。
に従って当該演算対象(複数のこともある。)から変換できる演算対象型を受け付ける。
非テンプレートの非メンバ候補のいずれとも同じ仮引数型並びをもたない。
組込みの代入演算子に対しては,左演算対象の変換に次の制約を設ける。
―
左演算対象を保持するための一時変数は,導入しない。
―
組込み候補の最左の仮引数と型を一致させるために左演算対象に変換を施す場合,利用者定義変換を適用
しない。
その他の演算子には,この制約はない。
多重定義解決のための候補関数の集合は,メンバ候補,非メンバ候補 及び 組込み候補の和集合とする。実引数並
びは,その演算子のすべての演算対象とする。候補関数の集合から,
及び
の規定に従って,最良関数
を選択する
。
例
6
Q
&
R&
6
)
60
60 &
Q
6
&
)
&
''
)
として
)
が選択される。
R
多重定義解決で組込み候補が選択された場合,選択された演算関数に対応する仮引数の型に演算対象を変換する。
その後で,その演算子を対応する組込み演算子として扱い,
#
に従って解釈する。
演算子
V
の第
演算対象は,
V
関数を選択する場合には無視し,
V
関数を呼び出すときの実
引数とはしない。
V
から戻った後,その返却値 及び 元の第
演算対象に演算子
V
を適用する
。
演算子が,演算子
,単項演算子
0
又は 演算子
V
であって,二次候補関数がない場合,その演算子を組込み演算
子とみなし,
#
に従って解釈する。
参考
式中の演算子の検索規則は,関数呼出し中の演算子関数名の検索規則とは異なる。
例
6
Q
R&
)
6
6 &
"
Q
)
" &
&
R&
6
&
"33
Q
)
&
''
エラー
3
大域的演算子をメンバが隠ぺいする。
)
&
''
B>3
大域的な
)
を呼び出す。
R
注
候補関数の集合が空の場合,多重定義解決は,失敗とする。
注
6
関数の返却値の型がクラス型の場合,別の
6
関数を選択して呼び出すことになる。そのプロセスは,
6
関数が非クラス型を返却するまで続く。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
コンスト ラクタによる初期化
クラス型オブジェクトの直接初期化(
#
) 又は 同じ クラス型 若し くは
派生クラス型の式からのコピー初期化(
#
)を行う場合,多重定義解決は,コンストラクタを選択する。直接初期化
の場合,候補関数は,初期化すべきオブジェクトクラスのすべてのコンストラクタとする。コピー初期化の場合,候
補関数は,そのクラスの変換コンストラクタ(
)とし ,その実引数並びは,初期化子の括弧内の《式並び》と
する。
利用者定義変換によるクラスのコピー初期化
#
で規定した条件の下で,クラス型のオブジェクトのコ
ピー初期化の一部として,初期化子式を初期化されるオブジェクトの型に変換するために,利用者定義変換を呼び出
すことができる。多重定義解決を使って,呼び出すべき利用者定義変換関数を選択する。
:
;
を初期化するオブ
ジェクトの型,
をクラス型とすると,次のとおりに候補関数を選択する。
―
の変換コンストラクタ(
)は,候補関数とする。
―
初期化子式の型が
:
;
というクラス型の場合,
及び その基底クラスの変換関数を調べる。
内で隠
ぺいされていない変換関数であって,
0
修飾なしの型が
又は その派生クラスと同じ型を生じる関数を
候補関数とする。
:
への参照
;
を返す変換関数は,型
の左辺値を返すので,この候補関数の選択手順
では,
を生じる関数とみなす。
いずれの場合にも,その実引数並びは,元の初期化子式
個だけを実引数とする。
参考
その実引数は,コンストラクタの最初の仮引数 及び 変換関数の暗黙のオブジェクト仮引数と比較される。
#
変換関数による初期化
#
で規定した条件の下で,非クラス型のオブジェクトの初期化の一部として,ク
ラス型の初期化子式を初期化されるオブジェクトの型に変換するために,変換関数を呼び出すことができる。多重定
義解決を使って,呼び出すべき変換関数を選択する。
:
;
を初期化されるオブジェクトの型,
:
;
を初期化子
式の型(
はクラス型)とすると,次のとおりに候補関数を選択する。
―
及び その基底クラスの変換関数を調べる。
内で隠ぺいされていない変換関数であって,型
を生じ
る関数 又は 標準変換手順(
)によって型
に変換し うる関数を候補関数とする。
0
修飾付き
の型を返す変換関数は,この候補関数の選択手順では,
0
修飾なしの
を生じる関数とみなす。
:
への参照
;
を返す変換関数は,型
の左辺値を返すので,この候補関数の選択手順では,
を生じる
関数とみなす。
その実引数並びは,元の初期化子式
個だけを実引数とする。
参考
その実引数は,変換関数の暗黙のオブジェクト仮引数と比較される。
(
直接参照結合に対する変換関数による初期化
#
で規定した条件の下で,初期化子式に変換関数を作
用させた結果の左辺値に,参照を直接結合させることができる。多重定義解決を使って,呼び出すべき変換関数を選
択する。
:
;
を初期化される参照の基礎とする型,
:
;
を初期化子式の型,
をクラス型とすると,次のとお
りに候補関数を選択する。
―
及び その基底クラスの変換関数を調べる。
内で隠ぺいされていず,
:
;
への参照型を生じる関
数を,候補関数とする。ここで,
:
;
と
:
;
とは,参照互換(
#
)とする。
その実引数並びは,元の初期化子式
個だけを実引数とする。
参考
その実引数は,変換関数の暗黙のオブジェクト仮引数と比較される。
二次候補
'%
関数
文脈に対して作られた候補関数の集合(
)から,二次候補関数の集合を選択
する。更に,その集合から,実引数変換手順を比較して,もっとも適合する関数を選択する(
参照)
。二次候
補関数の選択では,変換手順の階級以外の,実引数と関数仮引数の関係を調べる。
第
段階として,二次候補関数になるためには,候補関数は,実引数並びの個数に合致するだけの個数の仮引数を
もたなければならない。
―
実引数並びに
個の実引数がある場合,ちょうど
個の仮引数をもつ候補関数は,すべて二次候補関数
になる。
―
個より少ない仮引数の候補関数の場合,仮引数並びに省略記号(
(((
)のある関数だけが二次候補関数
になる(
#
参照)。多重定義解決においては,対応する仮引数のない実引数は,
:
省略記号に合致
;
す
る関数とみなす(
参照)
。
―
個より多い仮引数をもつ候補関数の場合は,
#
番目の仮引数が省略時実引数(
(
)をもつ関数
だけが二次候補関数になる
。多重定義解決においては,仮引数並びの右の部分を削り,ちょうど
個の仮引数並びにする。
注
の規定によって,
番目より後の仮引数も省略時実引数をもたなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)*
第
段階として,
+
が二次候補関数になるには,それぞれの実引数に,暗黙変換手順(
)が存在し,その
実引数が
+
の対応する仮引数に変換することができなければならない。仮引数が参照型の場合,暗黙変換手順は,参
照の結合演算を含む。そして,右辺値に非定値への参照を結合することはできないという事実が,その関数が二次候
補になることができるか否かに影響を与える(
参照)
。
最良二次候補関数
関数
+
の
"
番目の実引数に対する暗黙変換手順
"/"+
は,次のとおりとする。
―
+
が静的メンバ関数の場合,任意の関数を
,
とするとき,
"/+
は,
"/,
よりも良くも悪くもな
いと定義し ,逆に
"/,
は,
"/+
よりも良くも悪くもないと定義する
。
―
そうでない場合,
"/"+
は,実引数並び中の
"
番目の実引数を二次候補関数
+
の
"
番目の仮引数の型に
変換する暗黙変換手順と定義する。
で暗黙変換手順を定義し ,
で暗黙変換手順がどん
な場合に他よりも良いか悪いかを定義する。
上の定義を前提として,すべての実引数
"
に対し,
"/"+
が
"/"+
より悪くはなくて,更に次のいずれかの条
件が成り立つ場合に,二次候補関数
+
は,二次候補関数
+
よりも良いと定義する。
―
ある
に対して,
"/
+
が
"/
+
よりも良い変換手順である場合
―
そうでなくて,
+
が非テンプレートの関数であって,
+
が関数テンプレート特殊化である場合
―
そうでなくて,
+
及び
+
が関数テンプレート特殊化であって,
+
の関数テンプレートのほうが,
##
の部分順序規則によって
+
のテンプレートより強い特殊化である場合
―
そうでなくて,文脈が利用者定義変換の初期化(
#
,
#
及び
(
参照)であって,
+
の返
却値の型から目的の型(つまり,初期化される実体の型)への標準変換手順が,
+
の返却値の型から目
的の型への標準変換手順よりも良い変換手順である場合
例
6
Q
6 &
&
&
R
&
%
&
''
(
に変換なしを続けたほうが,
''
(
に
への変換を続ける
''
よりも良い。
%
&
''
あいまい
3
両方とも変換の可能性があり,
''
ど ちらも他より良くはない。
他のすべての二次候補関数よりも良い二次候補関数が一つだけ存在する場合,それが多重定義解決の選択した関数
とする。そうでない場合,その呼出しは不適格とする
。
例
9
!
&
9!
&
&
%
.&
Q
90
&
''
これはあいまいとなる。
''
0
→
!
は,
0
→
!
よりも良いが,
''
→
は,
→
よりも良い。
90
L? &
''
9!
を呼び出す。
''
0
→
!
は,
0
→
!
よりも良く,かつ
''
L?
→
と
L?
→
は判別がつかない。
90
ZZ &
''
9!
を呼び出す。
''
0
→
!
が
0
→
!
よりも良く,かつ
R
''
→
は,
→
よりも良い。
注
関数が静的メンバ関数の場合,ここの定義によって,第
実引数(暗黙オブジェクト仮引数)は,その関数が他の関数よりも良いか悪
いかを決めるのに影響しない。
注
最良二次候補関数選択アルゴ リズムは,二次候補関数の個数に比例する計算量となる。まず,単純な勝ち抜き戦を行い,比較を行った
相手のいずれよりも悪くない関数
を見つける。
と直接比較されなかった関数
についてみると,
が勝ち抜きのある時点で別の
関数
と比較され,
が
よりも良くなかったことが分かっているので,
は最良の関数にはなりえない。つまり,その
が最良の
関数であるか 又は 最良関数が存在しないかのいずれかとなる。そこで,第
のパスを行い,
が他のすべての二次候補関数よりも良
いことを検証すればよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
最良の二次候補関数が,宣言が複数されている関数に決着し ,それらの宣言 又は それらの宣言が《
!
宣言》に
よって参照している宣言の複数で省略時の仮引数が指定されていて,その結果としてその関数が二次候補関数に選択
されていた場合,そのプログラムは不適格とする。
例
6
Q
Y7Y
%
/ &
R
"
Q
Y7Y
%
/ &
R
633&
"33&
Q
* &
''B>3
省略時の実引数は,二次候補関数になるために使用しない。
&
''
エラー
3
省略時の実引数が
+
度見つかる。
R
暗黙変換手順
暗黙変換手順とは,関数呼出しの実引数を,対応する関数の仮引数の型に変換するための
変換の手順とする。この変換の手順とは,
で規定している暗黙変換のこととする。したがって,単一の式によるオ
ブジェクト 又は 参照の初期化のための規則に従う(
#
及び
#
参照)
。
暗黙変換手順では,実引数のもつ型,
0
修飾 及び 左辺値性,並びに それらが対応する仮引数の特性に合致するよ
うにど う変換されるかだけを考慮する。他の特性,例えば ,生存期間,記憶域種別,境界調整,実引数のアクセス可
能性,実引数がビットフィールド であるか否かなどは,無視する。したがって,実引数と仮引数の対に対して暗黙変
換手順が定義できたとしても,最終的な解析において実引数から仮引数の変換が不適格となることがある。
適格な暗黙変換手順とは,次のいずれかとする。
―
標準変換手順(
)
―
利用者定義変換手順(
)
―
省略記号変換手順(
)
次にあげる状況で候補関数となった利用者定義変換関数の実引数に対しては,あてはめるものを標準変換手順 及び
省略記号変換手順に限定する。
―
のクラスのコピー初期化の第
段階で一時オブジェクトのコピーのために呼び出される場合
―
,
#
及び
(
のすべての場合
仮引数の型が参照の場合は,
で規定する。
仮引数の型が参照でない場合,暗黙変換手順は,実引数式から仮引数へのコピー初期化にならう。暗黙変換手順と
は,実引数式を仮引数型の右辺値に変換するのに必要な変換とする。
参考
仮引数がクラス型の場合にも,この箇条における定義ではその操作を概念的に変換とみなす。実際の初
期化は,コンストラクタを使って定義されるので,変換とはいわない。
最上位の
0
修飾の違いは,初期化自体に吸収され,変換とはしない。
例
型
6
の仮引数は,型
6
の実引数から初期化することができる。その場合の暗黙変換手順は,恒等手
順とし ,
6
から
6
への変換を含まない。
仮引数がクラス型であり,実引数式が同じ型の場合,その暗黙変換手順は,恒等変換とする。仮引数がクラス型であ
り,実引数式がその派生クラス型の場合,その暗黙変換手順は,派生クラスを基底クラスに変換する派生基底変換と
する。
参考
このような標準変換は,実際には存在しない。暗黙変換手順の記述においてだけ,派生基底変換が存在
する。
派生基底変換の階級は,
:
変換
;
とする(
参照)
。
すべての文脈において,暗黙のオブジェクト仮引数へ変換する場合 及び 代入演算子の左演算対象へ変換する場合,
あてはめるのを結果用の一時オブジェクトを作らない標準変換手順だけに限る。
実引数を仮引数の型に合致させるのに変換が不要の場合,その暗黙変換手順は,恒等変換だけからなる標準変換手
順とする(
参照)
。
実引数から仮引数への変換手順が見つからない場合 又は 変換が不適格の場合,その暗黙変換手順を作ることがで
きない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
実引数を仮引数型に変換するいくつかの異なる変換手順が存在する場合,その仮引数に関連付ける変換手順は,あ
いまい変換手順と称する特別な変換手順と定義する。
で規定する暗黙変換手順の階級付けにおいては,あい
まい変換手順は,他の利用者定義変換手順と区別することができない利用者定義手順として扱われる
。
あいまい変換手順を使う関数が最良の二次候補関数として選択された場合,その呼出しは,その一つの実引数の変
換があいまいになるという理由で,不適格とする。
標準変換手順,利用者定義変換手順 及び 省略記号変換手順の三つの暗黙変換手順について,次に規定する。
標準変換手順
表
*
は,
で規定している変換を,左辺値変形,修飾調整,昇格 及び 変換の四つの排
他的な区分に分類する。
参考
この区分は,左辺値性,
0
修飾,データ表現という点で直交している。左辺値変形は,型の
0
修飾 及
び データ表現を変更しない。修飾調整は,型の左辺値性 及び データ表現の型を変更しない。昇格 及び
変換は,型の左辺値性 及び
0
修飾を変更しない。
参考
で規定したとおり,標準変換手順は,それ自身への恒等変換( つまり無変換)であるか,残りの四つ
の区分の中の一つから三つまでの変換で構成されるかである。標準変換手順では,それぞれの区分からの
変換は,高々一つしか許されない。手順中に複数の変換がある場合,次に示す順に変換を適用する。
―
左辺値変形
―
昇格 又は 変換
―
修飾調整
表
*
の各変換は,対応する階級(
:
厳密合致
;
,
:
昇格
;
, 又は
:
変換
;
)をもつ。それらは,標準変換手順の階級付
けに用いる(
参照)
。変換手順の階級は,その手順中の各変換の階級 及び 参照結合の階級(
)に
よって次のとおり決める。
―
手順中の変換 又は 参照結合のいずれかの階級が
:
変換
;
である場合,その変換手順の階級は,
:
変換
;
と
する。
―
手順中の変換 又は 参照結合に
:
変換
;
階級のものがなく,そのいずれかの階級が
:
昇格
;
である場合,そ
の変換手順の階級は,
:
昇格
;
とする。
―
それ以外の場合,その変換手順の階級は,
:
厳密合致
;
とする。
表
*
変換
変換
区分
階級
部分箇条
変換不要な場合
恒等
:
厳密合致
;
左辺値右辺値変換
左辺値変形
:
厳密合致
;
配列ポインタ変換
関数ポインタ変換
修飾変換
修飾調整
:
厳密合致
;
汎整数昇格
昇格
:
昇格
;
#
浮動小数点昇格
(
注
異なる利用者定義変換が含まれる場合にだけ一つの実引数に対する複数の変換手順が存在するという理由で,あいまい変換手順は,利
用者定義変換手順に階級付けされる。あいまい変換手順は,それが少なくとも二つの利用者定義変換手順(それぞれが異なる利用者定義
変換をもつ)を表すという理由から,他の利用者定義変換手順と区別することができないし ,他のど の利用者定義変換手順もそれらの中
の少なくとも一つとは区別することはできない。この規則は,一つの仮引数に対してあいまい変換手順があるという理由で,その関数が
二次候補に入らなくなることを防ぐ。
例
,1
"
"
,'1
1
,
"
1
1
7
7
,'1
1
&
%"
&
%7
,
.1
%.1
あいまい
.
→
7
は,コンストラクタ,
.
→
"
は,コンストラクタも変換関数もある。
この規則がない場合,
%"
は,
%.
の呼出しの二次候補関数から除外され,多重定義解決は,
%7
を選択し ,それを呼
び出すことになるが,明らかにそれは最良の関数ではない。一方,
%,
が宣言されている場合は,
%,
との
厳密合致
は,
%"
に合致するどの手順よりも良いので,
%.
は,その
%,
に解決される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
表
*
変換( 続き)
変換
区分
階級
部分箇条
汎整数変換
変換
:
変換
;
)
浮動小数点変換
浮動小数点汎整数変換
*
ポインタ変換
ポインタメンバ変換
論理値変換
利用者定義変換手順
利用者定義変換手順は,最初の標準変換手順,利用者定義変換(
) 及び 第
の標準変換手順を,この順に並べて構成する。利用者定義変換がコンスタラクタで指定された場合(
),最初
の標準変換手順は,元の型をコンストラクタの実引数の要求型に変換する。利用者定義変換が変換関数で指定された
場合(
),最初の標準変換手順は,元の型を変換関数の暗黙のオブジェクト仮引数に変換する。
第
の標準変換手順は,利用者定義変換の結果を目標の型に変換する。暗黙変換手順は初期化なので,利用者定義
変換手順の最良の利用者定義変換を選択するにあたって,利用者定義変換による初期化に対しての特殊規則を適用す
る(
及び
参照)
。
利用者定義変換がテンプレート変換関数によって指定された場合,第
の標準変換手順は,
:
厳密合致
;
階級をもっ
ていなければならない。
クラス型の式から同じ クラスの型への変換の階級は,
:
厳密合致
;
とする。クラス型の式からその基底クラスへの変
換の階級は,
:
変換
;
とする。これらの変換でコピーコンストラクタ(すなわち,利用者定義変換関数の一つ)が呼び
出されることは関係しない。
省略記号変換手順
省略記号変換手順は,関数呼出しの実引数が,呼び出される関数の省略記号の仮引
数の指定と合致した場合に生じる。
参照結合
参照型の仮引数が実引数式に直接結合(
#
)する場合,その暗黙変換手順は,実引数式の
型が仮引数の型の派生クラスであれば ,派生基底変換とし ,そうでなければ ,恒等変換とする(
参照)
。
例
6
QR&
"
3
6
QR
&
60 &
"0 &
%
&
''
\\
厳密合致
ZZ
の
"0
を呼び出すのであって
''
\\
変換
ZZ
の
60
は,呼び出さない。
実引数式に変換関数を作用させた結果に仮引数が 直接結合する場合,その暗黙変換手順は,利用者定義変換手順
(
) 及び 第
の標準変換手順とする。後者は,変換関数が仮引数の型の派生クラスの型の実体を返す場合
には派生基底変換とし ,そうでない場合には恒等変換とする。
参照型の仮引数が実引数式に直接結合されない場合,その変換手順は,
に従って実引数式を参照の基礎と
する型に変換するのに必要な変換手順とする。概念的には,その変換手順は,その基礎とする型の一時変数を実引数
式でコピー初期化することに対応する。最上位の
0
修飾の違いは,その初期化自体に吸収されるので,変換の一部
とはならない。
非定値への参照を右辺値に結合させる必要がある場合,標準変換手順を作ることができない。
(ただし ,暗黙のオ
ブジェクト仮引数への結合は,例外とする。その場合の特殊規則は,
で規定する。)
参考
例えば,候補関数が非定値を参照する仮引数( 暗黙のオブジェクト仮引数以外)をもち,対応する実引
数が一時変数であるか,参照を初期化するために一時変数を作る必要があるかである場合(
#
),その
候補関数は,二次候補関数になることができない。
しかし ,参照を個々の実引数に結合する場合のその他の制約は,標準変換手順を作る際に影響しない。
例
:
への参照
;
という仮引数をもつ関数は,対応する実引数が
型のビットフィールド であっても,二
次候補関数になりうる。暗黙変換手順では,
型のビットフィールドを
型の左辺値として扱い,その
仮引数と厳密に合致する。その関数が多重定義解決で選択された場合,その呼出しは,ビットフィールド
に非定値への参照を結合することができない(
#
)という理由によって不適格となる。
修飾を付加した参照互換な式に参照を結合することは,標準変換の階級に影響する(
及び
#
参照。)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
暗黙変換手順の階級付け
ここでは,より良い変換手順とより良い変換との間の関係をもとに,暗黙変換
手順の部分順序を定義する。暗黙変換手順
が,それらの規則によって
よりも良い変換手順であると定義され
た場合,
は,
よりも悪い変換手順とする。
が
よりも良い変換手順でも悪い変換手順でもない場合,
と
は,区別不可能な変換手順という。
暗黙変換手順の基本形式ど うしを(
に定義しているとおり)比較する場合は,次のとおりとする。
―
標準変換手順(
)は,利用者定義変換手順 及び 省略記号変換手順よりも良い変換手順とする。
―
利用者定義変換手順(
)は,省略記号変換手順(
)よりも良い変換手順とする。
二つの同一形式の暗黙変換手順は,次に示す規則のいずれにも該当しなかった場合,区別不可能とする。
―
標準変換手順
が別の標準変換手順
よりも良いのは,次のいずれかの場合とする。
で規定する標準形式で二つの変換手順を比較して,
が
の真部分手順となって
いる場合(ただし ,左辺値変形を除く。恒等変換手順は,恒等変換ではない変換手順の部分手
順と考える。)
の階級が
の階級よりも良い場合 又は
と
が同じ階級で,次に定める規定によって
区別できる場合
及び
の修飾変換だけが異なっており,それらが,類似の型
及び
を生じ(
参
照),かつ,型
の
0
修飾情報が,型
の
0
修飾情報の真部分集合になっていて,
が
推奨しない文字列リテラル配列からポインタへの変換でない場合
例
! &
! &
&
%
0 &
''
!
を呼び出す。
及び
が参照結合(
#
)であり,それらの参照が参照する型が最上位の
0
修飾を除い
て同一の型であり,かつ,
によって初期化される参照の参照型が,
によって初期化され
る参照の参照型より強い
0
修飾である場合
例
0 &
0 &
0 &
&
&
%
&
''
0
を呼び出す。
%
&
''
あいまい
5
Q
3
&
&
R&
50
5
Q
( &
''
533
を呼び出す。
( &
''
533
を呼び出す。
R
―
利用者定義変換手順
が別の利用者定義変換手順
よりも良いのは,
及び
が同一の利用者定
義変換関数 又は コンストラクタをもっており,かつ
の第
の標準変換手順のほうが,
の第
の標
準変換手順よりも良い場合とする。
例
6
Q
&
R
&
&
&
%
&
''
を呼び出す。
''
理由は,
→
のほうが
''
→
よりも良いから。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
標準変換手順は,その階級によって順位付けされる。
:
厳密合致
;
のほうが
:
昇格
;
よりも良く,
:
昇格
;
のほうが
:
変換
;
よりも良い。同じ階級の二つの変換手順は,次のいずれの規則も適用することができない場合,区別不可能と
する。
―
ポインタの変換 又は メンバへのポインタの変換でない変換ど うしでは,
への変換がどれよりも良い。
―
クラス
"
がクラス
6
の直接 又は 間接の派生クラスである場合,
"!
から
6!
への変換は,
"!
から
!
へ
の変換よりも良く,
6!
から
!
への変換は,
"!
から
!
への変換よりも良い。
―
クラス
"
がクラス
7
の直接 又は 間接の派生クラスであり,クラス
7
がクラス
"
の直接 又は 間接の派生
クラスである場合,次のとおりとする。
7!
から
"!
への変換は,
7!
から
6!
への変換よりも良い。
例
6
QR&
"
3
6
QR&
7
3
"
QR&
7
!&
6
! &
"
! &
%
&
''
"
!
を呼び出す。
型
7
の式を型
"0
の参照に結合するほうが,型
7
の式を型
60
の参照に結合するよりも良い。
633!
から
"33!
への変換は,
633!
から
733!
への変換よりも良い。
7
から
"
への変換は,
7
から
6
への変換よりも良い。
#
"!
から
6!
への変換は,
7!
から
6!
への変換よりも良い。
(
型
"
の式の型
60
の参照への結合は,型
7
の式の型
60
の参照への結合よりも良い。
)
"33!
から
733!
への変換は,
633!
から
733!
への変換よりも良い。
"
から
6
への変換は,
7
から
6
への変換よりも良い。
参考
利用者定義変換による初期化の第
の標準変換手順を比較する文脈では,比較される変換手順は異なる
元の型をもつ(
参照)
。その他の文脈では,元の型は同一であり,目標の型が異なる。
多重定義関数のアドレス
実引数をもたない多重定義関数の名前の使用は,いくつかの文脈では,その多重定
義集合の中の特定の関数に対する,関数,関数へのポインタ 又は メンバ関数へのポインタとして解決する。その文
脈の中では,関数テンプレート名を,多重定義関数集合の名前とみなす。選択された関数は,その文脈中で要求され
ている目標の型に合致する型をもつ関数とする。目標は,次のいずれかであってもよい。
―
初期化されるオブジェクト 又は 参照(
#
,
#
)
―
代入の左辺(
#)
)
―
関数の仮引数(
#
)
―
利用者定義演算子の仮引数(
#
)
―
関数,演算子関数 又は 変換の返却値(
((
)
―
明示的型変換(
#
,
#*
,
#
)
―
型でないテンプレート仮引数(
)
多重定義関数の名前の前に,演算子
0
を置いてもよい。多重定義関数の名前を,上に掲げた文脈を除き,実引数なし
で使ってはならない。
参考
多重定義関数の名前を囲む冗長な括弧は,無視される(
#
参照)
。
名前が関数テンプレートの場合,テンプレート実引数の導出を行う(
参照)
。実引数の導出が成功した場
合,その結果のテンプレート実引数並びを使って,一つの関数テンプレート特殊化を作り,それを多重定義関数の集
合に加える。
非メンバ関数 及び 静的メンバ関数は,型
:
関数へのポインタ
;
又は 型
:
関数への参照
;
の目標に合致する。非静的
メンバ関数は,型
:
メンバ関数へのポインタ
;
の目標に合致する。その場合,多重定義メンバ関数の集合からメンバ
関数を選択するために,メンバへのポインタの関数型を用いる。非静的メンバ関数が選択された場合,多重定義関数
の名前の参照は,
#
の規定に従って,メンバへのポインタという形式をもっていなければならない。
複数の関数が選択された場合,その集合に非テンプレートの関数があるときは,関数テンプレート特殊化は除外す
る。更に,
##
の部分順序規則によって,ある関数テンプレート特殊化
+
の関数テンプレートよりも特化され
た関数テンプレートをもつ別の関数テンプレート特殊化がある場合,
+
は除外する。それらを除外した後で,唯一
の関数が選択されなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
例
&
&
!
%
0&
''
を選択
!
%
0&
''
を選択
!
(((
%
0&
''
エラー:型が合致しない
0
%
&
''
を選択
0
%
&
''
を選択
Q
! 0&
''
キャスト式による選択
R
の初期化が不適格である理由は,
に型
(((
をもつものが定義されていないからであって,あ
いまいだからではない。もう一つの例を示す。
5
Q
&
&
R&
533!L
%
0533&
''
B>
!+
%
0533&
''
エラー
3
合致しない
!*
%
0533&
''
B>
533!M
%
0533&
''
エラー
3
合致しない
533!/
%
0533 &
''
エラー
3
メンバへのポインタ
''
構文として不適格
!-
%
0533 &
''
B>
参考
及び
が共に多重定義関数の場合,
0
又は それと同等の式
を解決するには,
及び
のそれぞれの可能性の直積を考える。
参考
関数へのポインタ型から別の関数へのポインタに変換する標準変換(
)は存在しない。特に,
"
が
#
の公開基底クラスであっても,次のとおりとなる。
#!
&
"!
!L
%
0&
''
エラー
#! &
!+ "!
%
0&
''
エラー
#
多重定義演算子
次のいずれかの演算子関数識別子を名前としてもつ関数宣言は,演算子関数を宣言する。演
算子関数は,演算子関数識別子を名前とする演算子の実装と呼ぶ。
演算子関数識別子
3
演算子
演算子
テンプレート仮引数並び
演算子
3
次の演算子のいずれか
ST
ST
)
V
!
'
U
W
0
1
X
[
%
)%
V%
!%
'%
U%
W%
0%
1%
%
%
%%
[%
%
%
00
11
))
VV
V!
V
ST
参考
は,関数呼出し 演算子(
#
)であり,
ST
は,添字付け演算子(
#
)である。演算子
ST
,
ST
,
及び
ST
は,
個以上の字句から成る。
)
,
V
,
!
及び
0
は,単項 及び
項のいずれの形式とも多重定義することができる。
次の演算子は,多重定義することができない。
(
(!
33
23
前処理記号
及び
(
(
)も多重定義することができない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
演算子関数は,通常直接に呼び出されることはない。その代りに,その実装する演算子を評価することによって呼
び出される(
#
〜
#)
参照)
。しかし ,演算子関数は,演算子関数識別子を関数呼出し構文の関数名に使うこ
とによって,明示的に呼び出すこともできる(
#
参照)
。
例
$
%
() &
''
$
%
)&
!
%
$
! &
割付け関数,解放関数,
,
ST
,
及び
ST
は,
)
で規定する。次に示す特性と制約は,
)
で明示的に規定していない場合には,適用されない。
演算子関数は,非静的メンバ関数 又は 非メンバ関数でなければならず,少なくとも一つの仮引数の型が,クラス,
クラスの参照,列挙体 又は 列挙体の参照のいずれかでなければならない。演算子の優先順位,結び付き 及び 演算対
象数は,変更することができない。演算子
%
,
( 単項の)演算子
0
及び 演算子
(コンマ)の型ごとにあらかじめ定
義されている意味は,特定のクラス型 及び 列挙型ごとに,それらの演算子を実装する演算子関数を定義することに
よって変更することができる。演算子関数は,他の基底クラスの関数と同じく継承される。
基本型に適用されるあらかじめ定義された演算子のいくつかにおける個別の特性( 例えば,
))
≡
)%L
)は,演算
子関数においては成立する必要がない。
)%
など のいくつかのあらかじめ定義された演算子が基本型に適用される場
合,左辺値演算対象を必要とするが,演算子関数には必要としない。
演算子関数は,特に明示する場合を除き,省略時実引数(
(
)をもつことができない。演算子関数は,対応する
演算子がとる仮引数と同じ個数の仮引数をもたなければならない。それを
#
〜
#)
に規定する。
#
〜
#)
で明示されていない演算子は,
#
又は
#
の規則に従い通常の単項演算子 及び
項演算
子として振る舞う。
#
単項演算子
前置の単項演算子は,仮引数なしの非静的メンバ関数(
*
) 又は
個の仮引数をもつ非メ
ンバ関数として実装しなければならない。したがって,前置の単項演算子
N
に対し ,
N
は,
(N
又は
N
のいずれにも解釈することができる。両方の形式の演算子関数が宣言されている場合,ど ちらに解釈
するかは,
の規則によって決まる。後置の単項演算子
))
及び
VV
については,
#)
に規定する。
同一演算子の単項 及び
項の形式は,同じ名前をもつとして扱う。
参考
したがって,単項演算子が,それを取り囲む有効範囲から
項演算子を隠ぺいすることがありうるし ,
その逆もありうる。
#
項演算子
項演算子は,
個の仮引数をもつ非静的メンバ関数(
*
)又は
個の仮引数をもつ非メンバ関数
として実装しなければならない。したがって,
項演算子
N
に対し,
N
は,
(N
又は
N
のいずれにも解釈することができる。両方の形式の演算子関数が宣言されている場合,どちらに解釈するかは,
の規則によって決まる。
#
代入
代入演算子は,
個の仮引数をもつ非静的メンバ関数として実装しなければならない。代入演算子が
利用者によって宣言されていない(
参照)場合,コピー代入演算子
%
が,クラスごとに暗黙に宣言さ
れるので,基底クラスの代入演算子は,常に派生クラスのコピー代入演算子によって隠ぺいされる。
コピー代入演算子を含むすべての代入演算子は,仮想であってもよい。
参考
派生クラス
#
が基底クラス
"
をもち,
"
に仮想のコピー代入演算子が宣言されている場合,
#
のコピー
代入演算子は,
"
の仮想コピー代入演算子を上書きしない。
例
"
Q
%
&
"0
%
"0 &
R&
#
3
"
Q
%
&
#0
%
"0 &
R&
#
L&
#
+&
"!
%
0L&
Q
V%
OO
&
''
#33%
を呼び出す。
!
%
OO&
''
同上
V%
+
&
''
#33%
"0
を呼び出す。
!
%
+&
''
同上
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
L
%
+&
''
暗黙宣言の
#33%
#0
R
''
を呼び出す。
#
関数呼出し
は,非静的メンバ関数でなければならないが,仮引数の個数は任意とする。
は,省略時実引数をもつことができ,次の関数呼出し構文を実装する。
後置式
式並び
ここで,
《後置式》は,評価されてクラスオブジェクトとなり,空かもしれない《式並び》が,そのクラスの
メンバ関数の仮引数並びと合致する。したがって,型
のクラスオブジェクト
に対し ,
33
L
+
*
が存在し,多重定義解決(
)においてそれが最良の関数に選択された場合,
L (((
という呼出しは,
(
L (
((
と解釈される。
##
添字付け
ST
は,
個の仮引数をもつ非静的メンバ関数でなければならない。
ST
は,次
の添字付け構文を実装する。
後置式
S
式
T
したがって,型
のクラスオブジェクト
に対して
33STL
が存在し ,多重定義解決(
)によっ
て,それが最良の関数であると選択された場合,添字式
ST
は,
(ST
と解釈される。
#(
クラスメンバアクセス
V
は,仮引数なしの非静的メンバ関数でなければならない。
V
は,次の
V
を使ったクラスメンバアクセス構文を実装する。
後置式
V
識別子式
33V
が存在し,多重定義解決(
)において,それが最良の関数であると選択された場合,式
V
は,クラス型
のオブジェクト
に対し ,
(V
V
と解釈される。
#)
増加と減少
利用者定義関数
))
は,前置 及び 後置の演算子
))
を実装する。その関数が,仮引数
なしのメンバ関数,又は
個のクラス型 若しくは 列挙型の仮引数をもつ非メンバ関数の場合,その関数は,その型
のオブジェクトに対する前置の増加演算子
))
を定義する。その関数が,
個の仮引数をもつメンバ関数( 型
の
仮引数でなければならない。) 又は
個の仮引数をもつ非メンバ関数( 第
仮引数は,型
でなければならない。)
の場合,その関数は,その型のオブジェクトに対する後置の増加演算子
))
を定義する。演算子
))
を使って後置の
増加を呼び出す場合,型
の実引数の値は,
になる
。
例
5
Q
3
50
)) &
''
前置
))
5
)) &
''
後置
))
R&
J
Q
R&
J0
))J0 &
''
前置
))
J
))J0
&
''
後置
))
5
J
Q
))&
''
()) &
))&
''
()). &
))&
''
)) &
))&
''
))
. &
()) &
''
明示的呼出し
))
に同じ
()). &
''
明示的呼出し
))
に同じ
)) &
''
明示的呼出し
))
に同じ
))
. &
''
明示的呼出し
))
に同じ
R
前置 及び 後置の減少演算子も,同じように扱う。
(
組込み演算子
#
で規定する組込み演算子を表現する候補演算子関数を,ここで規定する。それらの候補関数
は,
で規定した多重定義解決の処理に加わるが,それ以外の目的では使われない。
参考
組込み演算子は,非クラス型の演算対象しかとらず,かつ,演算子の多重定義解決は,演算対象式がも
ともとクラス型 又は 列挙型の場合にしか発生しないので,演算子の多重定義解決が組込み演算子として
解決されるのは,次のいずれかの場合に限る。
注
明示的に
88
を呼び出す
0883
のような式では,この特別な規則はなく,
88
の実引数は,
となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
―
演算対象がクラス型であって,その利用者定義の変換が,その演算子に適切な非クラス型に変
換する場合
―
演算対象が列挙型であって,その利用者定義の変換が,その演算子に適切な型に変換する場合
ここで示す候補演算子関数には,組込み演算子として許されないものも含まれる。
に規定すると
おり,多重定義解決で組込み演算子が選択された後,式は,
#
に規定する組込み演算子の要求に従うので,
そこでは,意味規則上のさらなる制約が課される。組込み候補演算子関数と同じ名前 及び 同じ仮引数の
型をもつ利用者定義の候補関数がある場合,その組込み演算子関数は,隠ぺいされて候補関数の集合には
含まれない。
ここでは,
:
昇格された汎整数型
;
という用語は,汎整数昇格で作られた汎整数型を指すために用いる。
( 例えば
及び
を含むが,
は含まない。)同様に,
:
昇格された算術型
;
という用語は,汎整数型に昇格されたもの 及
び 浮動小数点型を指すために用いる。
参考
昇格された汎整数型 又は 昇格された算術型が必要なすべての場合に,列挙型の演算対象は,汎整数昇
格によってアクセス可能となる。
を算術型とし ,
*
#
を
又は 空とするすべての対
*
#
に対して,次の形式の候補演算子関数が存
在する。
0
))
0 &
))
0
&
を論理型ではない算術型とし ,
*
#
を
又は 空とするすべての対
*
#
に対して,次の形式の候補
演算子関数が存在する。
0
VV
0 &
VV
0
&
を
0
修飾付き 又は
0
修飾なしのオブジェクト型とし ,
*
#
を
又は 空とするすべての対
*
#
に
対して,次の形式の候補演算子関数が存在する。
!
0
))!
0 &
!
0
VV!
0 &
!
))!
0
&
!
VV!
0
&
0
修飾付き 又は
0
修飾なしのすべてのオブジェクト型
に対して,次の形式の候補演算子関数が存在する。
0
!! &
すべての関数型
に対して,次の形式の候補演算子関数が存在する。
0
!! &
すべての型
に対して,次の候補演算子関数が存在する。
!
)! &
すべての昇格された算術型
に対して,次の形式の候補演算子関数が存在する。
) &
V &
すべての昇格された汎整数型
に対して,次の形式の候補演算子関数が存在する。
X &
をクラス型とし ,
を
と同じ型 又は
の派生クラスとし ,
をオブジェクト 又は 関数型とし ,
*
及び
*
を《
0
修飾子列》とするすべての五つ組
*
*
に対して,次の形式の候補演算子関数が
存在する。
0
V!
7L!
7+33! &
ここで,
*
は,
*
及び
*
の和集合とする。
昇格された算術型
-
及び
のすべての対に対して,次の形式の候補演算子関数が存在する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
!
&
'
&
)
&
V
&
&
&
%
&
%
&
%%
&
[%
&
ここで,
-
は,型
-
及び
の間の通常の算術変換の結果とする。
0
修飾付き 又は
0
修飾なしのすべてのオブジェクト型
に対して,次の候補演算子関数が存在する。
!
)!
P &
0
ST!
P &
!
V!
P &
!
)
P
! &
!
ST
P
! &
をオブジェクト型へのポインタとするすべての
に対して,次の形式の候補演算子関数が存在する。
P
V
&
すべてのポインタ型 又は 列挙型
に対して,次の形式の候補演算子関数が存在する。
&
&
%
&
%
&
%%
&
[%
&
すべてのメンバ型へのポインタ
に対して,次の形式の候補演算子関数が存在する。
%%
&
[%
&
昇格された汎整数型
-
及び
のすべての対に対して,次の形式の候補演算子関数が存在する。
U
&
0
&
W
&
1
&
&
&
ここで
-
は,型
-
及び
の間の通常の算術変換結果とする。
-
を算術型とし ,
*
#
を
又は 空とし,
を昇格された算術型とするすべての三つ組
-
*
#
に対し
て,次の形式の候補演算子関数が存在する。
0
%
0
&
0
!%
0
&
0
'%
0
&
0
)%
0
&
0
V%
0
&
を任意の型とし ,
*
#
を
又は 空とするすべての対
*
#
に対して,次の形式の候補演算子関数が
存在する。
!
0
%!
0
! &
をメンバへのポ インタ型とし ,
*
#
を
又は 空とするすべての対
*
#
に対して,次の形式の候補
演算子関数が存在する。
0
%
0
&
を
0
修飾付き 又は
0
修飾なしのオブジェクト型とし,
*
#
を
又は 空とするすべての対
*
#
に
対して,次の形式の候補演算子関数が存在する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
!
0
)%!
0
P &
!
0
V%!
0
P &
-
を汎整数型とし ,
*
#
を
又は 空とし ,
を昇格された汎整数型とするすべての三つ組
-
*
#
に
対して,次の形式の候補演算子関数が存在する。
0
U%
0
&
0
%
0
&
0
%
0
&
0
0%
0
&
0
W%
0
&
0
1%
0
&
次の形式の候補演算子関数が存在する。
[ &
00
&
11
&
昇格された算術型
-
及び
のすべての対に対して,次の形式の候補演算子関数が存在する。
2
&
ここで,
-
は,型
-
及び
の間の通常の算術変換結果とする。
参考
候補関数に関するこの箇条でのすべての規定と同じく,この宣言は,多重定義解決のための組込み演算
子として示しただけであって,演算子
2
を多重定義することはできない。
をポインタ 又は メンバへのポインタ型とするすべての
に対して,次の形式の候補演算子関数が存在する。
2
&
テンプレート
テンプレートは,クラス群 又は 関数群を定義する。
テンプレート宣言
3
テンプレート仮引数並び
宣言
テンプレート仮引数並び
3
テンプレート仮引数
テンプレート仮引数並び
テンプレート仮引数
《テンプレート宣言》中の《宣言》は,次のいずれかでなければならない。
―
関数 又は クラスを,宣言しているか定義している。
―
クラステンプレート 又は クラステンプレート内に入れ子になったクラスの,メンバ関数,メンバクラス
又は 静的データメンバを定義している。
―
クラスのメンバテンプレート 又は クラステンプレートのメンバテンプレートを定義している。
《テンプレート宣言》は,
《宣言》の一つをなす。
《テンプレート宣言》は,その中の《宣言》が関数,クラス 又は 静
的データメンバを定義している場合,定義となる。
《テンプレート宣言》は,名前空間有効範囲 又は クラス有効範囲の宣言としてだけ出現することができる。関数
テンプレート宣言では,その《宣言子識別子》が《テンプレート名》でなければならない( すなわち
,
《テンプレー
ト識別子》であってはならない。)
。
参考
クラステンプレート宣言では,そのクラス名が《テンプレート識別子》の場合,その宣言は,クラステ
ンプレートの部分特殊化を宣言する(
#
参照)
。
《テンプレート宣言》,明示的な特殊化 又は 明示的な具現化において,その宣言の《初期化宣言子並び》に含ま
れる宣言子は,高々一つでなくてはならない。これらの宣言がクラステンプレートを宣言する場合は,宣言子を含ん
でいてはならない。
テンプレート名は,結合をもつ(
#
参照)
。メンバでない関数テンプレートは,内部結合をもつことができる。そ
の他のテンプレート名は,外部結合をもたなければならない。内部結合をもつテンプレートから生成される実体は,
他の翻訳単位で生成される実体のいずれとも異なる。テンプレート,テンプレートの明示的な特殊化(
)
) 又は
クラステンプレートの部分特殊化は,
"
結合をもってはならない。これらの結合が,
"
又は
"##
以外の場合,その
動作は,処理系定義とする。テンプレートの定義は,単一定義規則(
)に従わなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
参考
関数テンプレート 及び クラステンプレートのメンバ関数に対する省略時実引数は,テンプレート具現
化(
#
)の目的では,定義と考えられる。そのため,それらも単一定義規則に従わなければならない。
クラステンプレートは,
#
に規定する場合を除き,同じ有効範囲(
)にある,別のテンプレート,クラス,
関数,オブジェクト,列挙体,列挙子,名前空間,又は 型の名前と,同じ 名前をもっていてはならない。関数テン
プレートが,同じ名前の非テンプレートの関数 又は 同じ名前の別の関数テンプレートと多重定義してあってもよい
(
参照)ことを除き,名前空間有効範囲 又は クラス有効範囲で宣言されたテンプレート名は,その有効範囲
において一意でなければならない。
次に示す名前空間有効範囲の宣言 又は 定義の前には,キーワード
を付けることができる。
―
非インラインの関数テンプレート
―
非インラインのメンバ関数テンプレート
―
クラステンプレートの非インラインのメンバ関数
―
クラステンプレートの静的データメンバ
を付けて宣言したテンプレートを,その宣言と同じ 翻訳単位で定義した場合,その定義を移出する
?1
という。キーワード
を含む最初のテンプレート宣言は,定義の前になければならない。
クラステンプレートを移出すると宣言することは,その翻訳単位で定義してある,そのクラステンプレートの非イ
ンラインのメンバ関数,静的データメンバ,メンバクラス,メンバクラステンプレート 及び 非インラインのメンバ
関数テンプレートのすべてを移出すると宣言することと等価とする。
無名の名前空間で定義したテンプレートは,移出してはならない。どのテンプレートも,一つのプログラムでちょ
うど 一度だけしか移出してはならない。処理系は,この規則への違反に診断メッセージを出力する必要はない。移出
していないテンプレートは,その特殊化をどこかの翻訳単位で明示的に具現(
)
)していない限り,暗黙に具現
(
)
)されるそれぞれの翻訳単位で,定義しなければならない(
)
参照)
。診断メッセージは必要としない。
移出したテンプレートの場合は,具現される翻訳単位で宣言だけすればよい( 必ずしも定義する必要はない)。移出
及び インラインの両方を指定して宣言した関数テンプレートは,インラインとして扱い,移出しない。
参考
処理系は,テンプレートの具現化を含む翻訳単位よりも先に,移出するテンプレートの定義を含む翻訳
単位をコンパイルするように利用者に要求してもよい。
テンプレート 仮引数
《テンプレート仮引数》の構文は,次のとおりとする。
テンプレート仮引数
3
型仮引数
仮引数宣言
型仮引数
3
識別子
識別子
%
型識別子
識別子
識別子
%
型識別子
テンプレート仮引数並び
識別子
テンプレート仮引数並び
識別子
%
識別子式
《テンプレート仮引数》において,
及び
は,意味的に同じものとして扱う。
の後に《修
飾なし識別子》を書く形は,テンプレートの型仮引数を名付けるために用いる。
の後に《修飾付き識別子》
を書く形は,非型の
《仮引数宣言》の中で,型を指定するために用いる。
《テンプレート仮引数》宣言に,記憶
域種別を指定してはならない。
参考
テンプレート仮引数は,クラステンプレートであってもよい。例を示す。
Q
'!
(((
!'
R&
>
H
7
%
@
Q
7>
&
7H
&
''
(((
注
テンプレートの,
《テンプレート仮引数》 及び 《テンプレート実引数》は,記述の上で,型として扱う。非型の仮引数 及び 非型の実
引数という用語は,型でもテンプレートでもない仮引数 及び 実引数に言及するために用いる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
R&
《型仮引数》は,そのテンプレート 宣言の有効範囲内で,その識別子を《型名》
(
又は
を伴って
宣言されている場合)又は 《テンプレート名》
(
を伴って宣言されている場合)として定義する。
参考
《テンプレート仮引数》の《識別子》の名前が,既存のクラス名と同じであるために,非型のテンプレー
ト仮引数 又は 《型仮引数》のいずれとも解釈できる場合,その《識別子》は,名前検索規則に従って
,
《型
仮引数》として扱われる。例を示す。
Q
'!
(((
!'
R&
&
Q
L
%
&
''
テンプレート仮引数の
及び
33
+
%
33&
''
広域名前空間のメンバ
及び
R
テンプレート
は,
という名前の《型仮引数》をもつ。クラス
の無名で非型の《テンプレート仮引数》
をもつのではない。
非型の《テンプレート仮引数》は,次のいずれかの型をもたなければならない。これらの型は,
0
修飾されていて
もよい。
―
汎整数型 又は 列挙型
―
オブジェクトへのポインタ 又は 関数へのポインタ
―
オブジェクトへの参照 又は 関数への参照
―
メンバへのポインタ
参考
その他の型は,次に示す規則に従って明示的に,又は 《テンプレート実引数》の形式に対する規則(
)
によって暗黙に,禁止されている。
《テンプレート仮引数》の型を決定する場合,その最上位の《
0
修飾子》は,無視される。
非型で非参照の《テンプレート仮引数》は,左辺値ではない。それには,値を代入してはならないし ,いかなる方法
でも値を変更してはならない。非型で非参照の《テンプレート仮引数》は,そのアドレスを得ることはできない。非
型で非参照の《テンプレート仮引数》を,参照への初期化子として使った場合,常に一時オブジェクトが用いられる。
例
50
Q
))&
''
エラー
3
テンプレート仮引数の値の変更
0&
''
B>
0&
''
エラー
3
非参照のテンプレート仮引数のアドレス
0
%
&
''
エラー
3
一時オブジェクトに結合された
でない参照
0
%
&
''
B>3
一時オブジェクトに結合された
参照
R
非型の《テンプレート仮引数》は,浮動小数点型,クラス型 又は
0
3
型として宣言してはならない。
例
5&
''
エラー
!
J&
''
B>
0
K&
''
B>
型
:
の配列
;
又は 型
:
を返す関数
;
をもつ非型の《テンプレート仮引数》の型は,それぞれ,型
:
へのポイン
タ
;
又は
:
を返す関数へのポインタ
;
に調整される。
例
!
E
Q
'!
(((
!'
R&
S/T
F
Q
'!
(((
!'
R&
&
E0
&
''
B>
F0
&
''
B>3
仮引数の調整による
S/T&
E
&
''
B>3
暗黙の実引数の変換による
F
$&
''
B>3
調整 及び 変換の両方による
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
《テンプレート仮引数》の中で,
%
の後に指定する《テンプレート実引数》
(
)は,省略時の《テンプレート実
引数》となる。省略時の《テンプレート実引数》は,すべての種類( 型,非型 及び テンプレート )の《テンプレー
ト仮引数》に指定できる。省略時の《テンプレート実引数》は,クラステンプレート宣言 又は クラステンプレート
定義の中に指定できる。省略時の《テンプレート実引数》は,関数テンプレート宣言,関数テンプレート定義, 及び
クラステンプレートのメンバ定義における《テンプレート仮引数並び》の中に,指定してはならない。省略時の《テ
ンプレート実引数》は,随伴テンプレート宣言の中に指定してはならない。
テンプレートの宣言 又は 定義で使用可能な省略時の《テンプレート実引数》の集合は,省略時の関数実引数と同
じ方法(
(
)で,有効範囲中にある定義 及び 宣言すべてから得られる省略時実引数を併合して得られる。
例
L
+
%
6&
L
%
+
6&
これは,次と同等とする。
L
%
+
%
6&
《テンプレート仮引数》が省略時の《テンプレート実引数》をもつ場合,それに続くすべての《テンプレート仮引
数》は,省略時の《テンプレート実引数》をもたなければならない。
例
L
%
+
"&
''
エラー
《テンプレート仮引数》が,同一有効範囲の二つの異なる宣言の両方で,省略時の実引数をもつことは許されない。
例
%
5&
%
5
Q
'!(((
!'
R&
''
エラー
《テンプレート仮引数》の有効範囲は,その宣言位置からそのテンプレートの最後までとする。特に,
《テンプレー
ト仮引数》は,それに続く《テンプレート仮引数》 及び それらの省略時実引数で使用できる。
例
!
G
%
5
Q
'!
(((
!'
R&
!
%
&
《テンプレート仮引数》は,それ自身の省略時実引数で使用してはならない。
非型の《テンプレート仮引数》に対する省略時の《テンプレート実引数》の構文解析では,入れ子でない最初の
を,演算子の
ではなく,
《テンプレート仮引数並び》の終わりとして扱う。
例
%
*
M
''
構文エラー
5
Q
'!
(((
!'
R&
%
*
M
''
B>
J
Q
'!
(((
!'
R&
テンプレート 特殊化の名前
テンプレート特殊化(
)
)は,
《テンプレート識別子》によって参照することが
できる。
テンプレート識別子
3
テンプレート名
テンプレート実引数並び
テンプレート名
3
識別子
テンプレート実引数並び
3
テンプレート実引数
テンプレート実引数並び
テンプレート実引数
テンプレート実引数
3
代入式
型識別子
識別子式
参考
書かれた名前をテンプレート宣言と結び付ける,すなわち,名前を《テンプレート名》として識別する
ためには,名前検索規則(
)が用いられる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
《テンプレート名》をテンプレート実引数で明示的に修飾する場合,その名前がテンプレートを示すことが判明し
ていなければならない。
名前検索(
)によって,名前が《テンプレート名》だと判明した後,その名前の後に
が続く場合,その
は,
常に《テンプレート実引数並び》の始まりとして扱われ,演算子の
として扱われることはない。
《テンプレート識
別子》を構文解析する場合,入れ子でない最初の
を,演算子の
ではなく,
《テンプレート実引数並び》の終
わりとして扱う。
例
5
Q
'!
(((
!'
R&
5
L+
L&
''
構文エラー
5L+
+&
''
B>
J
Q
'!
(((
!'
R&
J
5L
*&
''
B>
J5-
L
M&
''
B>3
J
5
-L
メンバテンプレートの特殊化の名前が,次のいずれかの場所に出現し ,後置式 又は 修飾付き識別子が,明示的に
《テンプレート仮引数》に依存する(
(
)場合,メンバテンプレート名の前にキーワード
を付けなけれ
ばならない。
―
《後置式》の中で
(
又は
V
の後
―
《修飾付き識別子》の中で 《入れ子名前指定子》の後
そうでない場合,その名前は,非テンプレートの名前として扱われる。
例
5
Q
3
$P
5!
&
$P
5!
&
R&
!
Q
!
L
%
V+.. &
''
不適格
3
は,演算子の
を意味する
!
+
%
V
+.. &
''
B>3
は,テンプレート実引数並びを開始する
33L.. &
''
不適格
3
は,演算子の
を意味する
33
L.. &
''
B>3
は,テンプレート実引数並びを開始する
R
キーワード
を前置した名前が,メンバテンプレートの名前でない場合,そのプログラムは,不適格とする。
参考
キーワード
は,クラステンプレートの非テンプレートのメンバに適用してはならない。
さらに,
《後置式》 又は 《修飾付き識別子》が,テンプレートの有効範囲中にない場合,メンバテンプレートの名前
の前にキーワード
を付けてはならない。
参考
の前置は,
の前置と同様に,それが厳密に必要ではない場所にも許される。すなわ
ち,
V
若しくは
(
の左辺の式 又は 《入れ子名前指定子》が,
《テンプレート仮引数》に従属していない
場合にも許される。
クラステンプレート特殊化を名付ける《テンプレート識別子》は,
《クラス名》
(
*
)とする。
テンプレート 実引数
《テンプレート実引数》には,
《テンプレート仮引数》の三つの形式,型,非型 及び テ
ンプレートに対応した三つの形式が存在する。
《テンプレート識別子》の中で指定する各《テンプレート 実引数》の
型 及び 形式は,そのテンプレートの《テンプレート仮引数並び》で宣言されている,対応する仮引数の型 及び 形式
に一致しなければならない。
注
&
,
,
若しくは
の中の《型識別子》を囲む
又は 《テンプレート識別子》
の《テンプレート実引数》を囲む
は,入れ子として扱われる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*#
例
6
Q
!
&
$&
3
6 &
0
ST &
0
Q
ST&
R
''
(((
R&
6
L+. &
&
''
は,標準ライブラリテンプレート
6
+*. &
6
*M. &
Q
LS*T
%
,&
+S*T
%
*(M
%
, N &
R
《テンプレート実引数》において,
《型識別子》と式とのあいまい性は,対応する《テンプレート仮引数》の形式に
関係なく,
《型識別子》として解決する
。
例
&
<
&
Q
&
''
\\ ZZ
は,型識別子。最初の
を呼び出す
R
《テンプレート実引数》の名前は,
《テンプレート実引数》として使用する位置でアクセス可能でなければならない。
参考
《テンプレート実引数》の名前が,
《テンプレート実引数》として使用する位置でアクセス可能な場合,
対応する《テンプレート仮引数》の名前が用いられるテンプレート具現化において,それ以上のアクセス
制限はない。
例
5
Q
&
R&
J
Q
3
F
Q
'!
(((
!'
R&
5F
&
''
B>3
F
は,アクセス可能
''
5J33F
は,型
J33F
の静的メンバをもつ
''
B>3
J33F
が非公開でもよい
R&
5J33F
&
''
エラー
3
F
は,アクセス可能でない
クラス型の《テンプレート実引数》の場合,テンプレート定義は,そのクラス型の《テンプレート実引数》の型のア
クセス可能でないメンバに対して,特別なアクセス権をもたない。
省略時の《テンプレート実引数》が用いられる場合,
《テンプレート実引数並び》は,空であってもよい。その場合
でも,
《テンプレート実引数並び》の指定として,空の括弧
を書かなければならない。
例
%
F&
F!
&
''
正しい。
F
F!
&
''
構文エラー
クラステンプレート特殊化の型をもつオブジェクトに対する明示的なデストラクタ呼出し(
)では,
《テンプ
レート実引数》を明示的に指定してよい。
注
省略時の《テンプレート実引数》では,
《テンプレート仮引数》の形式によって,
《テンプレート実引数》に許される形式が決まっている
ので,そのようなあいまい性はない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*(
例
6
Q
X6 &
R&
6!
6!
Q
V633X6 &
''
B>3
デストラクタ呼出し
V633X6
&
''
B>3
デストラクタ呼出し
R
テンプレート特殊化の具現化において,
《テンプレート実引数》の使用が不適格な構成要素を生じる場合,そのプロ
グラムは,不適格とする。
《テンプレート識別子》の中に出現するテンプレートが多重定義された関数テンプレートの場合,多重定義集合中
の,非テンプレートの関数 及び 《テンプレート実引数》に合致しない《テンプレート仮引数》をもつ関数テンプレー
トは,ど ちらも無視される。
《テンプレート仮引数》に合致する関数テンプレートが存在しない場合,そのプ ログラ
ムは,不適格とする。
テンプレート の型実引数
型を示す《テンプレート仮引数》に対応する《テンプレート実引数》は,
《型識別
子》でなければならない。
局所的な型,結合をもたない型,無名の型 又は これらの型から合成される型は,テンプレート《型仮引数》に対
応させる《テンプレート実引数》として用いてはならない。
例
5
Q
'!
(((
!'
R&
Q
F
Q
'!
(((
!'
R&
5F
*&
''
エラー
3
局所的な型をテンプレート実引数として使用
5F!
M&
''
エラー
3
局所的な型へのポインタをテンプレート実引数として使用
R
参考
テンプレート型実引数は,不完全型(
*
)であってもよい。
ある宣言において,
《テンプレート仮引数》に従属する型を介して関数型が得られ,それによって,関数宣言子の構
文形式を用いない宣言が関数型をもつことになる場合,そのプログラムは,不適格とする。
例
6
Q
&
R&
&
6
&
''
不適格
3
静的メンバ関数として
''
633
を宣言
テンプレート の非型実引数
非型 及び 非テンプレートの《テンプレート仮引数》に対する《テンプレート
実引数》は,次のいずれかでなければならない。
―
汎整数型 又は 列挙型の汎整数《定数式》
―
非型の《テンプレート仮引数》の名前
―
外部結合をもち,
0
《識別子式》と書かれたオブジェクトのアドレス 又は 関数のアドレス。オブジェクト
又は 関数には,関数テンプレート 及び 関数《テンプレート識別子》が含まれるが,静的でないクラスメ
ンバは含まれない。さらに,名前が関数 若しくは 配列を参照する場合,又は 《テンプレート仮引数》が
参照の場合,
0
は,省略可能とする。
―
#
で規定されるメンバへのポインタ
参考
文字列リテラル(
)は,これらの要求のいずれも満足していないので,
《テンプレート実引数》に
用いることができない。
例
!
5
Q
''
(((
5 &
5
!
Q
'!
(((
!'
R
R&
5 YF
Y
L&
''
エラー
3
テンプレート実引数としての
''
文字列リテラル
ST
%
YHY
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*)
5
+&
''
B>
参考
配列要素のアドレス,非静的クラスメンバの名前 及び 非静的クラスメンバのアドレスは,
《テンプレー
ト実引数》に用いることができない。
例
!
5
Q
R&
SL.T&
F
Q
&
&
R
&
50S+T
*&
''
エラー
3
配列要素のアドレス
50(
M&
''
エラー
3
非静的メンバのアドレス
50(
/&
''
エラー
3
0F33
を用いなければならない
50F33
-&
''
B>3
静的メンバのアドレス
参考
《テンプレート仮引数》が参照型をもつ場合,一時オブジェクト,名前のない左辺値 及び 外部結合を
もたない名前付きの左辺値を,それに対応する《テンプレート実引数》に用いることはできない。
例
0
7E<
"
Q
'!
(((
!'
R&
"L
+&
''
エラー
3
テンプレート実引数に対し
''
一時オブジェクトが作られてしまう
%
L&
"
L&
''
B>
非型のテンプレート実引数として用いられた式には,次の変換が行われる。非型のテンプレート実引数が,対応す
る《テンプレート仮引数》の型へ変換できない場合,そのプログラムは,不適格とする。
―
汎整数型 又は 列挙型の非型のテンプレート仮引数には,汎整数昇格(
#
) 及び 汎整数変換(
)
)が適
用される。
―
オブジェクトへのポインタ型をもつ非型のテンプレート仮引数には,修飾変換(
) 及び 配列からポイ
ンタへの変換(
)が適用される。
参考
特に
,
空ポインタ変換(
) 及び 派生から基底への変換(
)は,ど ちらも適用され
ない。
.
は,汎整数型の非型のテンプレート仮引数に対する正当な《テンプレート実引数》で
あるが,ポインタ型の非型のテンプレート仮引数に対する正当な《テンプレート実引数》では
ない。
―
オブジェクトへの参照型をもつ非型のテンプレート仮引数には,何の変換も適用されない。その参照によっ
て参照される型は,テンプレート実引数のより
0
修飾された( そうでなければ 同一の )型であってもよ
い。テンプレート実引数は,左辺値でなければならない。テンプレート仮引数は,そのテンプレート実引
数に直接束縛される。
―
関数へのポインタ型の非型のテンプレート仮引数には関数からポインタへの変換だけが適用される。テン
プレート実引数が多重定義された関数(又は それへのポインタ)の集合を表す場合,合致する関数は,そ
の集合から選ばれる(
参照)
。
―
関数への参照型をもつ非型のテンプレート仮引数には,何の変換も適用されない。
《テンプレート実引数》
が多重定義された関数の集合を示す場合,合致する関数は,その集合から選ばれる(
参照)
。
―
メンバ関数へのポインタ型をもつ非型のテンプレート仮引数には,何の変換も適用されない。テンプレー
ト実引数が多重定義されたメンバ関数の集合を表す場合,合致するメンバ関数は,その集合から選ばれる
(
参照)
。
―
データメンバへのポインタ型の非型のテンプレート仮引数には,修飾変換(
)が適用される。
例
!
5
Q
'!
(((
!'
R&
SL.T&
5
&
''
配列からポインタへの変換 及び 修飾変換
J
Q
'!
(((
!'
R&
J0
K
Q
'!
(((
!'
R&
J
&
K
$&
''
変換なしだが
修飾が追加されている点に注意
0 S/T
I
Q
'!
(((
!'
R&
S/T&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
I
&
''
変換なし
&
&
!
6
Q
'!
(((
!'
R&
60
&
''
を選ぶ
テンプレート のテンプレート 実引数
テンプレートを示す《テンプレート仮引数》に対する《テンプレート
実引数》は,
《識別子式》でなければならず,クラステンプレートの名前を表していなければならない。テンプレート
のテンプレート実引数と対応する仮引数との照合では,一次クラステンプレートだけを対象とする。すなわち,部分
特殊化は,その仮引数並びがテンプレートのテンプレート仮引数と合致するとしても,対象としない。
テンプレートのテンプレート仮引数に基づく特殊化が具現される場合,一次クラステンプレートと結び付く部分特
殊化(
#
)のすべてが対象になる。可視であれば選ばれるはずの特殊化が,具現化の位置で可視でない場合,そ
のプログラムは,不適格とする。診断メッセージは必要としない。
例
6
Q
''
一次テンプレート
&
R&
6!
Q
''
部分特殊化
&
R&
G
H
7
Q
H
&
H!
$&
R&
76
&
''
76
の中の
H
は,一次テンプレートを
''
用いるので,
((
は,型
\\ZZ
をもつ
''
76
の中の
H!
は,部分特殊化を用いる
''
ので,
($(
は,型
\\ZZ
をもつ
型の同等性
二つの《テンプレート識別子》は,次のすべてを満たす場合,同じ クラス 又は 関数を参照する。
―
テンプレート名が等しい。
―
同じテンプレートを参照する。
―
型の形式をもつ《テンプレート実引数》が,同じ型をもつ。
―
非型の形式をもつ汎整数型 又は 列挙型の《テンプレート実引数》が,同じ値をもつ。
―
非型の形式をもつポインタ型 又は 参照型の《テンプレート実引数》が,同じ外部オブジェクト 又は 関数
を参照する。
―
テンプレートの形式をもつ《テンプレート実引数》が,同じテンプレートを参照する。
例
次のプログラムでは,
及び
が同じ型をもつ宣言となっている。
8
$
Q
'!
(((
!'
R&
+!/L
+
&
L.+M
&
次のプログラムでは,
+
及び
*
が同じ型をもつ宣言となっている。その型は,
L
及び
M
とは異なる。
!P
Q
'!
(((
!'
R&
0P
L
L&
0P
+
+&
0P
+
*&
0
P
+
M&
#
テンプレート 宣言
《テンプレート識別子》,すなわち,
《テンプレート名》の後に《テンプレート実引数並び》
が続いた形は,一次テンプレート宣言の宣言に指定してはならない。
例
L
+
<
6L
+
<
Q
R&
''
エラー
L
<
L
<L
S<T &
''
エラー
参考
しかし ,この構文は,クラステンプレートの部分特殊化(
#
)では許される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
**
名前検索 及び 具現化においては,関数テンプレートの省略時実引数 及び クラステンプレートのメンバ関数の省
略時実引数は,定義とみなす。このとき,それぞれの省略時実引数は,その関数テンプレートの定義 又は 他の省略
時実引数とは関係のない別個の定義とする。
#
クラステンプレート
クラステンプレートは,共通の性質をもつ一群(一般には無限個)の型の,配置 及び
演算を定義する。
例
クラステンプレート
?
は,それ一つで,
のリスト,
のリスト 及び
F
へのポインタのリ
ストに,共通の定義を与えることができる。
例
配列を表すクラステンプレートは,次のように宣言できる。
6
Q
!
&
$&
3
6 &
0
ST &
0
Q
ST&
R
''
(((
R&
は,テンプレートを宣言し ,その宣言の中で《型名》
を使用することを示す。す
なわち,クラス
6
は,仮引数として
をもつ引数付き型である。
クラステンプレートの,メンバ関数,メンバクラス,静的データメンバ 又は メンバテンプレートを,クラステン
プレート定義の外側で定義する場合,それらは,クラステンプレートの《テンプレート仮引数》をその《テンプレー
ト仮引数》としたテンプレートとして定義する。そのメンバ定義に用いるテンプレート仮引数の名前は,クラステン
プレート定義で用いられたテンプレート仮引数の名前と異っていてもよい。ただし ,そのメンバ定義において,クラ
ステンプレート名に続くテンプレート実引数並びの中の実引数は,テンプレート仮引数並びにおける順序と同じ順序
で名付けなければならない。
例
L
+
6
Q
L &
+ &
R&
+
L
6+ L33L
Q
R
''
B>
+
L
6L +33+
Q
R
''
エラー
クラステンプレートの,再宣言,部分特殊化,明示的特殊化 又は 明示的具現化において,その《クラスキー》は,
元のクラステンプレート宣言と同じ種類でなければならない(
)#
参照)
。
#
クラステンプレートのメンバ関数
クラステンプレートのメンバ関数は,その宣言を含むクラステンプレー
ト定義の外側で定義してもよい。
例
次のプログラムは,三つの関数テンプレートを宣言している。
6
Q
!
&
$&
3
6 &
0
ST &
0
Q
ST&
R
''
(((
R&
この添字関数は,次に示す形で定義することもできる。
0
633
S
T
Q
.
11
$%
Y63
Y &
ST&
R
クラステンプレートのメンバ関数の《テンプレート実引数》は,そのメンバ関数を呼び出すオブジェクトの型の《テ
ンプレート実引数》によって決定される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
633
S
T
への《テンプレート実引数》は,その添字演算が適用される
6
によって決
定される。
6
L+. &
6
+*. &
LS*T
%
,&
''
633
ST
+S*T
%
, N &
''
633
ST
#
クラステンプレート のメンバクラス
クラステンプレートのクラスメンバは,その宣言を含むクラステン
プレート定義の外側で定義してもよい。
参考
そのクラスメンバは,具現化(
)
)を必要とするその最初の使用の前に定義しなければならない。
例を示す。
6
Q
"&
R&
633"!
L&
''
B>3
6
を定義してあることを必要とするが
''
633"
を定義してあることは,必要としない
633"
Q
R&
633"
+&
''
B>3
633"
を定義してあることを必要とする
#
クラステンプレート の静的データメンバ
静的データメンバの定義は,その静的メンバを含むクラステン
プレート定義を囲んでいる名前空間有効範囲にあってもよい。
例
5
Q
&
R&
533
%
.&
#
メンバテンプレート
テンプレートは,クラス 又は クラステンプレートの中で宣言することもできる。そ
のようなテンプレートを,メンバテンプレートと呼ぶ。メンバテンプレートは,クラス定義 又は クラステンプレー
ト定義の中 又は 外側のいずれでも定義できる。クラステンプレートのメンバテンプレートをそのクラステンプレー
ト定義の外側で定義する場合,そのメンバテンプレートには,クラステンプレートの《テンプレート仮引数》を指定
し ,さらに,それに続いて,そのメンバテンプレートの《テンプレート仮引数》を指定しなければならない。
例
Q
3
+
+0 &
+
+0
Q
'!
(((
!'
R
''
(((
R&
+
33
+0
Q
''
(((
R
局所クラスは,メンバテンプレートをもっていてはならない。メンバテンプレート名には,アクセス制御規則(
)
が適用される。デストラクタは,メンバテンプレートであってはならない。ある名前 及び 型をもった通常の( 非テ
ンプレート )メンバ関数とともに,同じ型に特殊化可能な同じ名前のメンバ関数テンプレートを同一のクラスの中に
宣言してもよい。両者が宣言してある場合,この名前と型との組合せは,明示的なテンプレート実引数並びを伴って
いるときを除いて,非テンプレートのメンバを参照する。
例
6
Q
&
+
+ &
R&
633
Q
R
''
非テンプレートメンバ
633
Q
R
''
テンプレート メンバ
Q
6
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(L &
''
非テンプレート
(ZZ &
''
テンプレート
(L &
''
テンプレート
R
メンバ関数テンプレートは,仮想としてはならない。
例
66
Q
7
7 &
''
エラー
&
''
B>
R&
メンバ関数テンプレートの特殊化は,基底クラスの仮想関数を上書きしない。
例
"
Q
&
R&
#
3
"
Q
&
''
"33
を上書きしない
Q
&
R
''
上書きしている関数
''
テンプレート具現化を呼び出している
R&
変換関数テンプレートの特殊化は,それと同じ 型への変換を行う非テンプレートの変換関数と同じ 方法で参照で
きる。
例
6
Q
! &
R&
633
! Q
.&
R
633
! Q
.&
R
''
特殊化
633
! &
''
明示的具現化
Q
6
&
!
&
%
(
! &
''
テンプレートの演算子
633
!
''
を明示的に呼び出す
R
参考
明示的なテンプレート実引数並びは,関数テンプレート名の直後にだけ指定できる。変換メンバ関数テ
ンプレート 及び コンストラクタメンバ関数テンプレートは,関数名を使用することなく呼び出される。
そのため,変換メンバ関数テンプレート 及び コンストラクタメンバ関数テンプレートに,明示的なテン
プレート実引数並びを与える方法は,存在しない。
変換関数テンプレートの特殊化は,名前検索では見つからない。その代わり,それを使用した文脈で可視なテンプ
レート変換関数すべてが考慮される。考慮する演算子それぞれに対して,実引数導出が成功した場合(
),そ
の結果得られる特殊化は,あたかも名前検索で見つかったかのように使用される。
派生クラスにおける
宣言は,基底クラスの変換関数テンプレートの特殊化を参照できない。
複数のテンプレート変換関数 及び/又は 非テンプレートの変換関数から最適な多重定義関数を選択するために,多
重定義解決(
) 及び 部分順序(
##
)が利用される。
#
随伴
クラス 又は クラステンプレートの随伴は,次のいずれかとする。
―
関数テンプレート
―
クラステンプレート
―
関数テンプレートの特殊化
―
クラステンプレートの特殊化
―
通常の( 非テンプレートの )関数
―
通常の( 非テンプレートの )クラス
随伴関数の宣言がテンプレート宣言ではない場合,その随伴の名前によって次のいずれかとする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
―
名前が《テンプレート識別子》のとき,それが修飾されているか否かにかかわらず,その随伴宣言は,関
数テンプレートの特殊化を参照する。
―
名前が《修飾付き識別子》で,かつ,その指定されたクラス 又は 名前空間に,合致する非テンプレート
の関数が見つかるとき,その随伴宣言は,その関数を参照する。
―
名前が《修飾付き識別子》で,かつ,その指定されたクラス 又は 名前空間に,合致する関数テンプレー
トの特殊化が見つかるとき,その随伴宣言は,その関数テンプレート特殊化を参照する。
―
その他の場合,名前は,通常の( 非テンプレートの)関数を宣言( 又は 再宣言)する《修飾なし識別子》
でなければならない。
例
&
!
! &
Q
''
(((
P &
!
&
!
!
&
7
7 &
&
C
&
''
(((
R&
クラステンプレート
の特殊化は,それぞれ,関数
を随伴としてもつ。
の場合,
明示的な《テンプレート実引数》が指定されていないので,クラステンプレート
の特殊化は,それ
ぞれ,適切な型の関数
を随伴としてもつ。この随伴は,関数テンプレートの特殊化ではない。随
伴
の場合,明示的な《テンプレート実引数》
が指定されているので,クラステンプレート
の特殊化は,それぞれ,適切な関数テンプレート
の適切な特殊化を随伴としてもつ。クラ
ステンプレート
の特殊化は,それぞれ,関数テンプレート
の特殊化すべてを随伴としてもつ。
同様に,クラステンプレートの特殊化は,それぞれ,そのクラステンプレート特殊化
を随伴と
してもち,クラステンプレート
の特殊化すべてを随伴としてもつ。
随伴関数宣言は,それがテンプレート 宣言でなく,その随伴の名前が修飾なしの《テンプレート 識別子》の場合,
最も近い名前空間有効範囲で宣言された関数テンプレートの特殊化を参照する。
例
A
Q
&
&
@
Q
&
&
6
Q
&
''
不適格
V
A33
&
''
B>
V
@33
&
''
B>
V
@33
の新しい宣言
&
&
''
不適格
V
633
R&
R
R
随伴テンプレートは,クラス 又は クラステンプレートの中で宣言してよい。随伴関数テンプレートは,クラス 又
は クラステンプレートの中で定義してよい。一方,随伴クラステンプレートは,クラス 又は クラステンプレートの
中で定義してはならない。随伴クラスの特殊化 又は 随伴関数テンプレートの特殊化は,すべて,随伴関係を定めた
クラス 又は クラステンプレートの随伴とする。
例
6
Q
"&
''
B>
Q
'!
(((
!'
R
''
B>
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
テンプレート 随伴宣言は,そのテンプレートの特殊化のすべてを,それらが暗黙に具現(
)
)されているか,
部分的に特殊化(
#
)されているか 又は 明示的に特殊化(
)
)されているかの別とは無関係に,テンプレー
ト随伴宣言を含むクラスの随伴とすることを指定する。
例
5
Q
6&
J
Q
R&
R&
6
Q
533J
&
R&
''
B>
6!
Q
533J
&
R&
''
B>
クラステンプレート中の随伴関数宣言内で関数を定義した場合,その関数は,そのクラステンプレートのそれぞれ
の具現化ごとに定義される。この定義は,たとえその関数が使用されない場合でも行なわれる。非テンプレートの関
数の宣言 及び 定義に適用される,複数の宣言・定義がある場合の制約と同じ制約が,これらの暗黙の定義にも適用
される。
参考
その関数定義が,それを囲むクラステンプレートの特殊化に対して不適格な場合,そのプログラムは,
その関数が使用されない場合でも不適格となる。
クラステンプレートのメンバは,非テンプレートのクラスの随伴として宣言してもよい。その場合,クラステンプ
レートの各特殊化の対応するメンバは,随伴関係を定めたクラスの随伴となる。
例
6
Q
"
Q
R&
&
R&
7
Q
633"&
633 &
R&
参考
随伴宣言は,それを囲む名前空間有効範囲(
(#
)のメンバの最初の宣言としてもよい。
随伴テンプレートは,局所クラスの中で宣言してはならない。
随伴宣言は,部分特殊化を宣言してはならない。
例
6
Q
R&
5
Q
6!&
''
エラー
R&
随伴宣言が関数テンプレートの特殊化を参照する場合,その関数の仮引数宣言は,省略時実引数を含んではならず,
その宣言の中に
指定子を使用してはならない。
#
クラステンプレート の部分特殊化
一次クラステンプレート宣言とは,クラステンプレート名が識別子のク
ラステンプレート宣言とする。クラステンプレート名が《テンプレート識別子》のテンプレート宣言は,その《テン
プレート識別子》で名付けられるクラステンプレートの部分特殊化となる( クラステンプレート部分特殊化と呼ぶ。)
。
クラステンプレート部分特殊化は,特殊化の実引数がその部分特殊化の実引数と合致する(
#
参照)場合に,
一次定義の代わりに用いられるもう一つのテンプレート定義となる。一次テンプレートは,そのテンプレートのすべ
ての特殊化より前に宣言しなければならない。テンプレートを部分的に特殊化する場合,その部分特殊化は,各翻訳
単位で,その部分特殊化の暗黙の具現化を生じ うる最初の使用より前に宣言しなければならない。診断メッセージは
必要としない。
部分特殊化が移出されたテンプレートの具現化で用いられ,かつ,その特殊化されていないテンプレート名が移出
されたテンプレート中で非従属な場合,その部分特殊化は,移出されたテンプレートの定義を含む翻訳単位において,
その定義より前に宣言しなければならない。同様の制限が明示的な特殊化に対しても適用される(
)
参照)
。
クラステンプレート部分特殊化は,それぞれが別個のテンプレートとし ,そのテンプレート部分特殊化のメンバそ
れぞれに対して,定義を与えなければならない(
#
参照)
。
例
L
+
<
6
Q
R&
''
L
<
6
!
<
Q
R&
''
+
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
L
+
<
6L!
+
<
Q
R&
''
*
6
!
/
Q
R&
''
M
L
+
<
6L
+!
<
Q
R&
''
/
最初の宣言は,特殊化されていない一次クラステンプレートを宣言している。
番目以降の宣言は,その
一次テンプレートの部分特殊化を宣言している。
テンプレート仮引数は,キーワード
の直後に続く
括弧で囲まれた並びの中に指定する。部分特殊化
のテンプレート実引数並びは,クラステンプレート名の直後に明示的に指定する。一次テンプレートでは,この並び
がテンプレート仮引数並びによって暗黙に指定される。そこに並ぶテンプレート実引数の順序は,テンプレート仮引
数並びでの出現の順序と同じとする。
例
上記の例で,一次テンプレートのテンプレート実引数並びは,
L
+
<
となる。
参考
一次テンプレート宣言で,テンプレート実引数並びを指定してはならない。
L
+
<
6L
+
<
Q
R&
''
エラー
クラステンプレート部分特殊化は,その定義を定義し うるすべての名前空間で,宣言 又は 再宣言できる(
#
及び
#
参照)
。
例
6
Q
7
Q
+
"
Q
R&
R&
R&
''
633733"+
の部分特殊化
+
633733"+!
Q
R&
633733"
!
&
''
部分特殊化を用いる
部分特殊化の宣言は,名前検索では見つからない。そのかわり,一次テンプレート名の使用に対して,その一次テ
ンプレートの既に宣言された部分特殊化のすべてが考慮に入れられる。そのため,
《
!
宣言》がクラステンプレー
トを参照している場合,その《
!
宣言》によって見つかる部分特殊化の集合が制限されることはない。
例
A
Q
L
+
6
Q
R&
''
一次テンプレート
R
A336&
''
一次テンプレートを参照する
A
Q
6
!
Q
R&
''
部分特殊化
R
6 !
&
''
一次テンプレートを参照する
宣言によって
''
見つかる部分特殊化を使用
非型の実引数は,それが非型の仮引数の名前の場合,特殊化されていないとする。その他の非型の実引数は,特殊
化されているとする。
クラステンプレート部分特殊化の実引数並びには,次の制限が適用される。
―
部分的に特殊化された非型の実引数式は,その実引数式が単純な《識別子》の場合を除き,部分特殊化の
テンプレート仮引数を含んでいてはならない。
例
<
=
6
QR&
<
6<)/
<!+
QR&
''
エラー
<
=
"
QR&
<
"<
<
QR&
''
B>
―
特殊化された非型の実引数に対応するテンプレート仮引数の型は,そのテンプレート部分特殊化の仮引数
に従属していてはならない。
例
7
QR&
7
L&
''
エラー
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
5
!P S5T
6
QR&
S/T&
5
65 0
Q
R&
''
エラー
―
テンプレート部分特殊化の実引数並びは,その一次テンプレートの暗黙の実引数並びと同一であってはな
らない。
テンプレート部分特殊化のテンプレート仮引数並びは,省略時のテンプレート実引数の値
を含んでいてはな
らない。
#
クラステンプレート 部分特殊化の合致
クラステンプレートが,そのクラスの具現化を必要とする文脈で
使用される場合,その具現化を,一次テンプレートを用いて生成するか 又は その部分特殊化の一つを用いて生成する
かを決定する必要がある。その決定は,クラステンプレート特殊化のテンプレート実引数と部分特殊化のテンプレー
ト実引数並びとを照合することで行う。
―
合致する特殊化が正確に一つ見つかる場合,その具現化は,その特殊化から生成する。
―
合致する特殊化が複数見つかる場合,部分順序規則(
#
)を用いて,他の特殊化すべてと比べてよ
り特殊化されている唯一の特殊化を見出す( 具現化は,その唯一の特殊化から生成する)。どの特殊化も
他の合致するすべての特殊化と比較して,より特殊化されてはいない場合,そのクラステンプレートの使
用はあいまいであり,プログラムは,不適格とする。
―
合致するものが見つからない場合,その具現化は,一次テンプレートから生成する。
部分特殊化は,その部分特殊化のテンプレート実引数が実際のテンプレート実引数並びから導出できる場合(
)
,
与えられた実際のテンプレート実引数並びに合致する。
例
6
L
L&
''
L
を用いる
6
!
L
+&
''
+
を用いる,
は
,
<
は
L
6
!
/
*&
''
M
を用いる,
は
6
!
L
M&
''
/
を用いる,
L
は
,
+
は
,
<
は
L
6!
!
+
/&
''
あいまい。
*
と
/
に合致する
非型のテンプレート実引数は,一次テンプレートの非型の仮引数への実際のテンプレート実引数の値からも導出で
きる。
例
上の
+
の宣言。
クラステンプレート特殊化を参照する型名( 例えば ,
6
L
)において,その実引数並びは,一次テン
プレートのテンプレート仮引数並びに合致しなければならない。特殊化のテンプレート実引数は,一次テンプレート
の実引数から導出される。
#
クラステンプレート 特殊化の部分順序
二つのクラステンプレート部分特殊化に対して,第
のクラステ
ンプレート部分特殊化が,第
のクラステンプレート部分特殊化と少なくとも同等に特殊化されているとは,次に示
す書換えによって得られる二つの関数テンプレートにおいて,第
の関数テンプレートが,関数テンプレートに対す
る順序規則(
##
)の上で,第
の関数テンプレートと少なくとも同等に特殊化されている場合とする。
―
第
の関数テンプレートは,第
の部分特殊化と同じテンプレート仮引数をもち,唯一の関数仮引数をも
つ。この関数仮引数の型は,第
の部分特殊化と同じテンプレート実引数をもつクラステンプレート特殊
化の型とする。
―
第
の関数テンプレートは,第
の部分特殊化と同じテンプレート仮引数をもち,唯一の関数仮引数をも
つ。この関数仮引数の型は,第
の部分特殊化と同じテンプレート実引数をもつクラステンプレート特殊
化の型とする。
例
<
=
5
Q
R&
<
=
5<
=
Q
R&
''
L
<
5<
<
Q
R&
''
+
<
=
5<
=
&
''
6
<
5<
<
&
''
"
関数テンプレートの順序規則に従うと,関数テンプレート
"
は,関数テンプレート
6
と比較して,より
特殊化されているので,部分特殊化
+
は,部分特殊化
L
と比較して,より特殊化されている。
注
それらを使用する方法は,存在しない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
#
クラステンプレート 特殊化のメンバ
クラステンプレート部分特殊化のメンバのテンプレート仮引数並び
は,そのクラステンプレート部分特殊化のテンプレート仮引数並びに合致しなければならない。クラステンプレート
部分特殊化のメンバのテンプレート実引数並びは,そのクラステンプレート部分特殊化のテンプレート実引数並びに
合致しなければならない。クラステンプレート部分特殊化は,別個のテンプレートとなる。クラステンプレート部分
特殊化のメンバは,一次テンプレートのメンバとは無関係とする。クラステンプレート部分特殊化のメンバは,定義
を必要とする方法で使用する場合,定義しなければならない。クラステンプレート部分特殊化のメンバの定義として,
一次テンプレートのメンバの定義が使用されることはない。クラステンプレート部分特殊化のメンバの明示的な特殊
化は,一次テンプレートの明示的な特殊化と同様の方法で宣言する。
例
''
一次テンプレート
<
6
Q
&
R&
<
6 <33
Q
R
''
クラステンプレート部分特殊化
6 +
Q
&
&
&
R&
''
クラステンプレート部分特殊化のメンバ
6 +33
Q
R
''
明示的な特殊化
6 +33
Q
R
Q
6 .
.&
6 +
+&
.( &
''
B>
,一次テンプレートのメンバの定義を用いる
+( &
''
B>
,部分特殊化のメンバの定義を用いる
+( &
''
B>
,明示的な特殊化のメンバの定義を用いる
+( &
''
不正,
6 +
に対する
の定義が存在しない
''
ここでは,その一次テンプレートは用いられない
R
クラステンプレートのメンバテンプレートが部分的に特殊化された場合,そのメンバテンプレート 部分特殊化は,
それを囲むクラステンプレートのメンバテンプレートとなる。それを囲むクラステンプレートが具現される(
)
及び
)
参照)場合,各メンバテンプレート部分特殊化に対する宣言も,そのクラステンプレート特殊化のメンバ
生成の一部として具現される。一次メンバテンプレートが,それを囲むクラステンプレートのある( 暗黙の)特殊化に
対して,明示的に特殊化されている場合,そのメンバテンプレートの部分特殊化は,それを囲むクラステンプレート
のその特殊化に対して無視される。メンバテンプレートの部分特殊化が,それを囲むクラステンプレートのある( 暗
黙の)特殊化に対して明示的に特殊化されている場合,その一次メンバテンプレート 及び その他の部分特殊化は,そ
れを囲むクラステンプレートのその特殊化に対しても考慮される。
例
6
Q
+
"
QR&
''
L
+
"+!
QR&
''
+
R&
+
633"
QR&
''
*
633"!
&
''
+
を用いる
633"!
&
''
*
を用いる
633"
&
''
L
を用いる
##
関数テンプレート
関数テンプレートは,共通の性質をもつ一群( 一般には無限個)の関数を定義する。
例
ソート関数の群は,次のように宣言することができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
6
Q
R&
60 &
関数テンプレートは,別の関数テンプレートと多重定義することができ,通常の( 非テンプレートの)関数とも多
重定義することができる。通常の関数は,関数テンプレートの生成され うる特殊化と,同じ名前 及び 同じ型をもっ
ていたとしても,関数テンプレートとは関係ない(すなわち,特殊化とみなされることはない)
。
##
関数テンプレート の多重定義
関数テンプレートを多重定義して,二つの異なる関数テンプレートの特殊
化が同じ型をもつようにすることができる。
例
''
L(
''
+(
! &
&
!
Q
!
Q
&
''
!
&
''
!!
''
を呼び出す
''
を呼び出す
R
R
そのような特殊化は,別個の関数とし ,単一定義規則(
)に違反しない。
関数テンプレート特殊化の呼出し情報は,その関数テンプレートの呼出し情報 及び 実際のテンプレート実引数( 明
示的に指定したものでも導出されたものでもよい。)で構成される。
関数テンプレートの呼出し情報は,その関数の呼出し情報,返却値の型 及び テンプレート仮引数並びで構成され
る。テンプレート仮引数の名前は,テンプレート仮引数をその呼出し情報の残りの部分と関係付ける場合にだけ意味
をもつ。
参考
多重定義解決がそれらを区別できない場合でも,二つの異なる関数テンプレートが,同一の返却値の型
及び 関数仮引数並びをもつことができる。
&
<
&
''
B>3
最初のテンプレートと多重定義
''
明示的なテンプレート実引数並びで区別可能
関数テンプレート宣言の関数仮引数並び 又は 返却値の型に,テンプレート仮引数を参照する式を用いる場合,そ
の式は,関数テンプレートの呼出し情報の一部とする。これは,ある翻訳単位の中の関数テンプレートの宣言と別の
翻訳単位のその関数テンプレートの別の宣言との結合を許すため,また逆に,異なるものとして意図された関数テン
プレートが互いに結合されないことを保証するために必要となる。
例
<
=
6<)=
6<
6= &
''
L
>
?
6>)?
6>
6? &
''
L
と同じ
<
=
6<V=
6<
6= &
''
L
とは異なる
参考
テンプレート仮引数を使用するほとんどの式は,非型テンプレート仮引数を使用するが,型仮引数を参
照することもできる。例えば ,テンプレート型仮引数を
$
演算子に使用することができる。
テンプレート仮引数を含む二つの式は,それらの式を含む二つの関数定義が,単一定義規則(
)を満たす場合,
等価とみなす。その場合,そのテンプレート仮引数を名付けるのに用いる字句は,一方の式のテンプレート仮引数を
名付けるのに用いられた字句を,他方の式の対応するテンプレート仮引数を名付けるのに用いられた字句で置き換え
ることができるならば ,異なっていてもよい。
例
<
=
6<)= &
''
L
>
?
6>)? &
''
L
と同じ
テンプレート仮引数を含む等価でない二つの式は,与えられた任意のテンプレート実引数の組に対し,その式の評価
結果が同じ値になる場合,機能等価とする。
二つの関数テンプレートは,それらが同じ有効範囲で宣言され,同じ名前をもち,同一のテンプレート仮引数並び
をもち,テンプレート仮引数を含む式の比較において,上の規則によって等価となる返却値の型 及び 仮引数並びを
もつ場合,等価とする。二つの関数テンプレートは,返却値の型 及び 仮引数並びにおいて,テンプレート仮引数を
含む式が,上の規則によって機能等価となることを除き,等価な場合,機能等価とする。機能等価であるが等価では
ない関数の宣言をプログラムが含む場合,そのプログラムは,不適格とする。診断メッセージは必要としない。
注
すなわち,非テンプレートの関数の宣言は,同じ名前をもつ関数テンプレート特殊化の多重定義の解決を手引きするだけではない。そ
うした非テンプレートの関数は,プログラムで使うには,定義しなければならず,関数テンプレート定義を用いて暗黙に具現されること
はない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
参考
この規則は,機能等価な宣言を異なるものとして扱うことを保証するための大きな努力を処理系に要求
することなく,等価な宣言が互いに結合されることを保証する。例えば ,次の例の最後の二つの宣言は,
機能等価であり,プログラムは不適格になる。
''
同じことが保証されている
<
6<
6<)L. &
<
6<
6<)L. &
''
異なることが保証されている
<
6<
6<)L. &
<
6<
6<)LL &
''
不適格,診断メッセージは必要ない
<
6<
6<)L. &
<
6<
6<)L)+)*)M &
##
関数テンプレート の部分順序
関数テンプレートが多重定義されている場合,関数テンプレート特殊化は,
テンプレート実引数導出(
)によって,複数の関数テンプレート宣言と対応付けられうる。そのため,その関
数テンプレート特殊化の使用は,あいまいになることがある。多重定義されている関数テンプレート宣言の部分順序
は,次の文脈で使用して関数テンプレート特殊化が参照する関数テンプレートを選択する。
―
関数テンプレート特殊化の呼出しに対する多重定義解決(
)
―
関数テンプレート特殊化のアドレスを得る場合
―
位置指定演算子
に対応する,関数テンプレート特殊化である位置指定演算子
が選択される場
合(
)
及び
#
参照)
―
随伴関数宣言(
#
),明示的な具現化(
)
)又は 明示的な特殊化(
)
)が,関数テンプレー
ト特殊化を参照する場合
二つの多重定義された関数テンプレートにおいて,一方が他方と比較して,より特殊化されているか否かは,それ
ぞれのテンプレートを順番に変換し ,実引数導出(
)を用いて比較することで決定できる。
変換は,次に従って行われる。
―
各型テンプレート仮引数に対し ,ある一意の型を合成し ,関数仮引数並び中 又は テンプレート変換関数
の場合の返却値の型中のその仮引数の出現を置き換える。
―
各非型テンプレート仮引数に対し,適切な型のある一意の値を合成し,関数仮引数並び中 又は テンプレー
ト変換関数の場合の返却値の型中のその仮引数の出現を置き換える。
―
各テンプレートテンプレート仮引数に対し,ある一意のクラステンプレートを合成し ,関数仮引数並び中
又は テンプレート変換関数の場合の返却値の型中のその仮引数の出現を置き換える。
変換された関数仮引数並びを用い,もう一方の関数テンプレートに対し,実引数導出を行う。変換されたテンプレー
トは,その導出が成功し ,かつ,導出された仮引数型が厳密に合致する(したがってその導出は暗黙の変換に依存し
ない)場合にだけ,もう一方と少なくとも同等に特殊化されている。
あるテンプレートは,それが,もう一方のテンプレートと少なくとも同等に特殊化されており,かつ,もう一方の
テンプレートが,それと同等以上に特殊化されてはいない場合にだけ,より特殊化されているとする。
例
6
Q
6 &
R&
&
! &
! &
&
0 &
0 &
60 &
Q
!&
&
''
!
は,
又は
!
と比較して,
''
より特殊化されている
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
&
''
あいまい
3
又は
0
6
$&
$ &
''
多重定義解決は,
60
を選択する
6
$+&
$+ &
''
60
が呼出し可でないので,
''
0
が呼び出される
R
使用されない省略記号 及び 省略時実引数の存在は,関数テンプレートの部分順序に影響を及ぼさない。
例
&
''
L
!
%L &
''
+
&
''
*
!
((( &
''
M
Q
!
&
&
''
+
を呼び出す
&
''
M
を呼び出す
R
(
名前解決
テンプレート定義では,次の
種類の名前を使用できる。
―
テンプレート自体の名前 及び テンプレート自体の中で宣言された名前
―
《テンプレート仮引数》に従属している名前(
(
)
―
テンプレート定義中で可視な有効範囲からの名前
テンプレートの宣言 又は 定義で使用され,かつ,
《テンプレート仮引数》に従属している名前は,それに適用可能
な名前検索によって型名が見つかる場合 及び その名前がキーワード
で修飾されている場合を除き,型を
名付けるとは見なされない。
例
''
"
は,ここに宣言されていない
5&
J
Q
K&
''
メンバクラスの先行宣言
Q
5!
L&
''
5
へのポインタを宣言
!
+&
''
へのポインタを宣言
J!
*&
''
J
へのポインタを宣言
K!
M&
''
K
へのポインタを宣言
336
6&
6!
/&
''
の
6
へのポインタを宣言
336!
-&
''
の
6
へのポインタを宣言
336!
,&
''
336
は型名ではない
3
''
336
に
,
を掛ける。 不適格
''
,
の可視の宣言は,存在しない
"!
N&
''
"
は型名ではない
3
''
"
に
N
を掛ける。 不適格
''
"
及び
N
の可視の宣言は,存在しない
R
R&
《修飾付き識別子》が型を参照し,その中の《入れ子名前指定子》が《テンプレート仮引数》に従属する(
(
)
場合,その《修飾付き識別子》は,キーワード
を前置して,
《詳述型指定子》
(
)#
)と型を指している
ことを示さなければならない。
例
詳述型指定子
3
(((
33
入れ子名前指定子
識別子
33
入れ子名前指定子
テンプレート識別子
(((
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
を前置した《修飾付き識別子》が型でなくなる形での《テンプレート実引数》を与えて,テンプレート
の特殊化が具現された場合,その特殊化は,不適格とする。
《修飾付き識別子》の検索には,
が前置されて
いても,通常の修飾付き名前の検索(
)が使用される。
例
6
Q
5
Q
R&
5&
R&
Q
335
&
''
不適格
3
メンバ型
5
でなく
''
データメンバ
5
を見つける
R
キーワード
は,テンプレートの宣言 及び 定義の中でだけ使用することができる。この許容対象には,次
も含まれる。
―
関数テンプレート 又は メンバ関数テンプレートの返却値の型
―
クラステンプレート 又は クラステンプレート内の入れ子クラスのメンバ関数定義に対する返却値の型
―
クラステンプレート 又は クラステンプレート内の入れ子クラスの静的メンバ関数の定義に対する《型指
定子》
キーワード
は,修飾付き名前にだけ適用しなければならない。しかし ,その名前が従属している必要はな
い。キーワード
は,従属名が用いられる文脈でだけ用いられなければならない。その文脈には,テンプレー
トの宣言 及び 定義が含まれるが,明示的な特殊化 及び 明示的な具現化の宣言は含まれない。キーワード
は,
《基底指定子》 又は 《メンバ初期化子》では許されない。それらの文脈では,
《テンプレート仮引数》に従属する
(
《修飾付き識別子》は,暗黙に型名とみなされる。
クラステンプレートの定義 又は クラステンプレートのメンバの定義において,そのクラステンプレートで既に宣
言されている,型を宣言しているメンバを修飾なしの名前で参照する場合,キーワード
は,必要ない。修
飾付き名前を用いて参照する場合は,その修飾子が単にクラステンプレートの名前だとしても,キーワード
を常に指定しなければならない。
例
6
Q
"&
633"
&
''
不適格
3
633"
の前に
が必要
633" &
''
不適格
3
633"
の前に
が必要
633"
&
''
B>
R&
どの名前が型名なのかを知ることで,個々のテンプレート定義の構文検査が可能になる。正しい特殊化を生成可能
なテンプレート定義に対し ,診断メッセージを出力してはならない。テンプレート定義に対し正しい特殊化が生成で
きず,そのテンプレートが具現されない場合,そのテンプレート定義は,不適格とする。診断メッセージは必要とし
ない。非従属な名前の中で用いられた型が,テンプレートが定義された時点で不完全であるがそれが具現された時点
では完全であり,その型の完全性がプログラムが適格であるか否かに影響を与える場合 又は プログラムの意味に影
響を与える場合,そのプログラムは,不適格とする。診断メッセージは必要としない。
参考
テンプレートが具現されれば,この規格の別の規則に従ってエラーが出力される。どの時点でエラーが
出力されるかは,処理系の質に依存する。
例
&
5
Q
''
(((
!
Q
%
&
''
533
が具現され,
への代入がエラーの場合,
''
診断メッセージが出力される
%
&
''
533
が具現されない場合でも
''
診断メッセージが出力され うる
%
&
''
533
が具現されない場合でも
''
診断メッセージが出力され うる
R
Q
)&
''
533
が具現されない場合でも
''
診断メッセージが出力され うる
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
R
R&
テンプレート定義で使用された名前の宣言が検索される場合,テンプレート仮引数に従属しない名前には,通常の
検索規則(
及び
参照)が用いられる。テンプレート仮引数に従属している名前の検索は,実際のテンプ
レート実引数が明らかになるまで延期される(
(
参照)
。
例
&
F
Q
!
&
&
3
F &
F
F0 &
Q
%
.&
&
))
ST
Z4Z&
R
''
(((
R&
上の例で,
は,
で宣言された局所変数
であり,
は,
F
で宣言されたメンバ
で
あり,
は,
で宣言された標準出力ストリームである。しかし ,必ずしもすべての宣言が,
そのように見つかるわけではない。実際の《テンプレート 実引数》が明らかになるまで,名前の解決を
延期しなければならない場合もある。例えば ,名前
は,
の定義の中で既知であ
り,その宣言は,
の中に見つかることは確かではあるが,
ST
の出力に必要とされる実際の
の宣言は,
の型がわかるまで明らかでない。
名前が,
《テンプレート仮引数》に従属しない(
(
参照)場合,その名前の宣言( 又は 宣言の集合)は,テン
プレート定義にその名前が現れた位置で有効でなければならない。名前は,その位置で見つかった宣言( 又は 宣言の
集合)に結合される。その結合は,具現化の位置で可視な宣言には影響されない。
例
&
Q
L &
''
L &
''
従属
&
''
従属
))&
''
従属
''
エラー
3
の宣言が見つからない
R
&
&
Q
+ &
''
を呼び出し,その後,
を
+
回呼び出す
ZZ &
''
を
*
回呼び出す
R
参考
名前検索においては,関数テンプレートの省略時実引数 及び クラステンプレートのメンバ関数の省略
時実引数は,定義とみなす(
#
参照)
。
(
局所的に宣言された名前
普通の( 非テンプレートの )クラスと同様に,クラステンプレートは,補整クラ
ス名をもつ(
*
参照)
。補整クラス名は,
《テンプレート実引数並び》を伴って用いても,伴わずに用いてもよい。
《テ
ンプレート実引数並び》を伴わずに用いた場合,その補正クラス名は,
で囲まれたクラステンプレートの《テンプ
レート仮引数》が続く補整クラス名と等価とする。
《テンプレート実引数並び》を伴って用いた場合,その補正クラ
ス名は,指定されたクラステンプレート特殊化( 現在の特殊化でも別の特殊化でもよい。)を参照する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
クラステンプレート特殊化 又は 部分特殊化の有効範囲の中において,
を伴わない補整クラス名は,
で囲んだ,
クラステンプレート特殊化 又は 部分特殊化の《テンプレート実引数並び》を伴う補整クラス名と等価とする。
例
J&
J
Q
J!
&
''
J
を意味する
J!
&
''
J
を意味する
R&
クラステンプレート 又は クラステンプレート特殊化の補整クラス名は,それが有効範囲中にある場合,
《テンプレー
ト実引数並び》を伴って用いても,伴わずに用いてもよい。
例
"
Q
"!
&
R&
#3
"
Q
#33"!
&
''
#33"
を意味する
R&
補整クラス名を見つける検索は,あいまいになる( 例えば ,二つ以上の基底クラスで見つかる)場合がある。見つ
%
かったすべての補整クラス名が同じ クラステンプレートに対する特殊化を参照し,その名前が《テンプレート実引数
並び》を伴う場合,その《テンプレート実引数並び》を伴う補正クラス名は,特殊化ではなくクラステンプレート自
身を参照し,あいまいではない。
例
"
Q
R&
#3
"
"
Q
#33"
&
''
エラー
3
あいまい
#33"
&
''
B>
R&
テンプレートの通常の名前(すなわち,補整クラス名ではなく,クラスを囲む有効範囲からの名前)が《テンプレー
ト実引数並び》を伴わずに用いられた場合,それは,テンプレートの特殊化ではなく,クラステンプレート自身を参
照する。
例
5
Q
5!
&
''
5
を意味する
5!
+&
5!
*&
335!
M&
''
エラー
3
テンプレート実引数並びを伴っていない
''
335
は,補整クラス名を参照しない
R&
クラステンプレートの有効範囲の中では,そのクラステンプレートに入れ子になったクラスの名前を修飾せずに参
3
照する場合,その入れ子になったクラスの名前は,それを囲むクラステンプレートの名前と等価とする。
例
6
Q
"
Q
R&
''
"
は,
633"
と等価であり,従って
633"
と等価であって,
''
従属している。
7
3
"
Q
R&
R&
《テンプレート仮引数》の有効範囲は,その宣言の位置からテンプレートの終わりまでとする。
《テンプレート仮
引数》は,それを囲む有効範囲の同じ名前の実体を隠す。
参考
これは,
《テンプレート仮引数》を,その後の《テンプレート仮引数》の宣言 及び その省略時実引数で使
用できるが,先行する《テンプレート仮引数》 及び その省略時実引数では使用できないことを意味する。
例
!
G
%
5
Q
'!
(((
!'
R&
!
%
&
また,
《テンプレート仮引数》をその基底クラスの指定で使用できることを意味する。
例
5
3
6
Q
'!
(((
!'
R&
J
3
Q
'!
(((
!'
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
基底クラスの指定に《テンプレート仮引数》を使用する場合,
《テンプレート実引数》として使用されるク
ラスは,クラステンプレートが具現される位置で,宣言されているだけでなく定義されていなければなら
ない。
《テンプレート仮引数》は,その有効範囲( 入れ子になった有効範囲を含む。)で再宣言してはならない。
《テンプ
レート仮引数》は,テンプレート名と同じ名前としてはならない。
例
J
Q
&
''
エラー
3
テンプレート仮引数の再宣言
Q
&
''
エラー
3
テンプレート仮引数の再宣言
R
R&
5
5&
''
エラー
3
テンプレート仮引数の再宣言
クラステンプレート定義の外側に現れるそのクラステンプレートのメンバの定義の中では,そのテンプレートのメ
ンバの名前が《テンプレート仮引数》の同じ名前を隠す。
例
6
Q
"
Q
'!
(((
!'
R&
&
R&
"
6"33
Q
"
&
''
6
の
"
,テンプレート仮引数ではない
R
クラステンプレート定義を含む名前空間の外側のそのクラステンプレートのメンバの定義の中では,
《テンプレート
仮引数》の名前がその名前空間のメンバの同じ名前を隠す。
例
A
Q
7
Q
R&
"
Q
&
R&
R
7
A33"7337
Q
7
&
''
7
は,テンプレート仮引数であって,
A337
ではない
R
クラステンプレート 又は クラステンプレートのメンバの定義の中では,
《テンプレート仮引数》
(
(
)に従属
しない基底クラスの名前のそれぞれに対して,その基底クラスの名前 又は その基底クラスのメンバの名前が《テン
プレート仮引数》
(
(
)と同じ場合,その基底クラスの名前 又は そのメンバの名前は,
《テンプレート仮引数》の
名前を隠す(
)
参照)
。
例
6
Q
"
Q
'!
(((
!'
R&
&
J&
R&
"
5
3
6
Q
"
&
''
6
の
"
&
''
エラー
3
6
の
は,型名ではない
R&
(
従属名
テンプレートの構成要素には,具現化ごとに異なる意味をもちうる要素がある。そのような構成要
素は,テンプレート仮引数に従属するという。特に,型 及び 式は,テンプレート仮引数の型 及び/又は 値に従属す
る(テンプレート実引数によって決定される)ことがあり,このことが,ある種の名前に対して,名前検索の文脈を
決定する。式は,
(テンプレート仮引数の型に )型従属する 又は( 非型のテンプレート仮引数の値に )値従属すること
がある。次の形式の式において,
《後置式》が《識別子》である場合,その《識別子》が従属名を示すのは,
《式並び》
中のいずれかの式が型従属式(
(
)の場合だけとする。
後置式
式並び
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
演算子の演算対象が型従属式の場合,その演算子も従属名となる。そのような名前は,結合されず,テンプレート具
現化の位置(
(
)で,テンプレート定義の文脈 及び その具現化の位置の文脈の両方を対象に検索される。
例
5
3
"
Q
336!
&
"!
Q
%
"33&
V))&
R
R&
クラス名
"
,型名
336
,名前
"33
及び
V
は,明示的に《テンプレート仮引数》に従属して
いる。
クラステンプレート 又は クラステンプレートのメンバの定義の中で,そのクラステンプレートの基底クラスが《テ
ンプレート仮引数》に従属する場合,修飾されていない名前の検索では,その基底クラスの有効範囲は,クラステン
プレート 又は メンバの定義においても,クラステンプレート 又は メンバの具現化においても,対象とならない。
例
6&
"
Q
6&
R&
5
3
"
Q
6
&
''
は,型
をもつ
R&
5
の定義における型名
6
は,大域名前空間有効範囲で定義された型定義名に結合され,基底クラス
"
で定義された型定義名には結合されない。
(この段落の第
の文は,
+"
によって削除された。)
例
6
Q
"
Q
'!
(((
!'
R&
&
J&
R&
&
J
3
Q
"
Q
'!
(((
!'
R&
"
&
''
J
で定義された
"
Q
%
&
R
''
33
J!
&
''
J
R&
J6
&
テンプレート実引数
6
のメンバ,
633"
,
633
及び
633J
は,
J6
の中の名前の結合に対して,影響を及ぼさない。
(
従属型
型は,それが次のいずれかである場合に従属する。
―
テンプレート仮引数
―
《入れ子名前指定子》を伴った《修飾付き識別子》。但し ,従属型を示す《クラス名》を含むか 又は その
《修飾なし識別子》が従属型を示す場合に限る。
―
0
修飾のない型が従属している場合の
0
修飾型
―
従属型で構成される複合型
―
従属型で構成される配列型 又は その大きさが値従属の定数式で指定される配列型
―
次のいずれかを満たす《テンプレート識別子》
―
テンプレート名が,テンプレート仮引数を指す。
―
テンプレート実引数のいずれかが,従属型そのもの,型従属の式 又は 値従属の式となっている。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
(
型従属式
式は,そのいずれかの部分式が型従属の場合,特に断りがない限り,型従属とする。
は,それが属するメンバ関数のクラス型が従属している場合,型従属(
(
)とする。
《識別子式》は,次のいずれかを含む場合,型従属とする。
―
従属型を用いて宣言された《識別子》
―
従属している《テンプレート識別子》
―
従属型を指定している《変換関数識別子》
―
従属型を示す《クラス名》を含む《入れ子名前指定子》
式が次の形式の場合,その式が型従属となるのは,その部分式のいずれかが型従属であったとしても,
《型指定子》,
《単純型指定子》 又は 《生成型識別子》によって指定された型が従属している場合だけとする。
単純型指定子
式並び
33
生成位置指定
生成型識別子
生成初期化子
33
生成位置指定
型識別子
生成初期化子
型識別子
式
型識別子
式
型識別子
式
型識別子
式
型識別子
キャスト式
次の形式の式は,
(その式の型が従属することがありえないため )型従属になりえない。
リテラル
後置式
(
擬似デストラクタ名
後置式
V
擬似デストラクタ名
$
単項式
$
型識別子
式
型識別子
33
キャスト式
33
S
T
キャスト式
代入式
(
値従属の式
定数式は,その部分式のいずれかが値従属の場合,特に断りがない限り,値従属とする。
《識別子》は,次の場合,値従属とする。
―
従属型を用いて宣言した名前
―
非型テンプレート仮引数の名前
―
汎整数型 又は 列挙型をもち,かつ,値従属な式で初期化した定数式
次の形式の式は,
《単項式》が型従属しているか 又は 《型指定子》が従属している場合,
(
$
《単項式》 及び
$
《型指定子》
が型従属でなくとも)値従属とする。
$
単項式
$
型識別子
次の形式の式は,
《型指定子》 又は 《単純型指定子》が従属しているか,
《式》 又は 《キャスト式》が値従属して
いる場合,値従属とする。
単純型指定子
式並び
型識別子
式
型識別子
式
型識別子
式
型識別子
キャスト式
(
従属するテンプレート 実引数
型《テンプレート実引数》は,それが指定する型が従属している場合,従
属しているとする。
汎整数型の非型《テンプレート実引数》は,それが指定する定数式が値従属している場合,従属しているとする。
汎整数型ではない非型のテンプレート実引数は,その型が従属している場合,又は 次のいずれかの形式をもち,従
属型を示す《クラス名》を指定する《入れ子名前指定子》を含む場合,従属しているとする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
修飾付き識別子
0
修飾付き識別子
テンプレートの《テンプレート実引数》は,それが《テンプレート仮引数》を示す場合,又は 従属型を示す《クラ
ス名》を含む《入れ子名前指定子》を伴う《修飾付き識別子》の場合,従属しているとする。
(
非従属な名前
テンプレート定義中で使用される非従属な名前は,通常の名前検索で見つけられ,使用され
た位置で結合される。
例
&
&
K
Q
3
Q
L &
''
を呼び出す
))&
''
不適格
3
関数を増加することはできない
''
この場所 又は 具現化の位置で
''
診断メッセージが出力され うる
R
R&
&
''
テンプレート定義の位置で有効範囲にない
''
L
の呼出しで対象にならない
(
従属名の解決
従属名の解決では,次の宣言からの名前が対象になる。
―
テンプレートの定義の位置において可視な宣言
―
具現化の文脈(
(
)及び 定義の文脈からの関数実引数の型に関連する名前空間からの宣言
(
具現化の位置
関数テンプレート 特殊化,メンバ関数テンプレート特殊化 又は クラステンプレートのメ
ンバ関数 若し くは クラステンプレートの静的データメンバの特殊化では,その特殊化が別のテンプレート特殊化の
中で参照され,かつ,その文脈がテンプレート仮引数に従属しており,そのためそれが暗黙に具現された場合,その
具現化の位置は,それを囲む特殊化の具現化の位置とする。そうでない場合,その特殊化の具現化の位置は,その特
殊化を参照する,名前空間有効範囲の宣言 又は 定義の直後とする。
関数テンプレート 又は クラステンプレートのメンバ関数を,その関数テンプレート 又は メンバ関数の省略時実
引数の定義を用いる形で呼び出す場合,その省略時実引数の具現化の位置は,その関数テンプレート 又は クラステ
ンプレートのメンバ関数の具現化の位置とする。
クラステンプレート特殊化,クラスメンバテンプレート特殊化 又は クラステンプレートのクラスメンバの特殊化
では,その特殊化が別のテンプレート特殊化の中で参照されていることから暗黙に具現され,その特殊化が参照され
る文脈がテンプレート仮引数に従属しており,かつ,それを囲むテンプレート特殊化に先行してそれが具現されてい
ない場合,その具現化の位置は,それを囲むテンプレートの具現化の位置の直前とする。そうでない場合,それらの
特殊化に対する具現化の位置は,その特殊化を参照する,名前空間有効範囲の宣言 又は 定義の直前とする。
仮想関数が,暗黙に具現される場合,その具現化の位置は,それを囲むクラステンプレート特殊化の具現化の位置
の直後とする。
明示的な具現化指示によって指定された特殊化( 一つでも複数でもよい )の場合,その具現化の位置は,明示的な
具現化指示の位置とする。
テンプレート実引数に従属する式の具現化の文脈は,同じ翻訳単位中にある,そのテンプレート特殊化の具現化の
位置より前に宣言されている外部結合をもつ宣言群とする。
関数テンプレート,メンバ関数テンプレート 又は クラステンプレートのメンバ関数 若しくは 静的データメンバの
特殊化は,一つの翻訳単位中で,具現化の位置を複数もっていてもよい。クラステンプレート特殊化では,一つの翻
訳単位中の具現化の位置は高々
箇所とする。どのテンプレートの特殊化も,複数の翻訳単位では,それぞれ具現化
の位置をもっていてもよい。二つの異なる具現化の位置が,単一定義規則(
)に従ってテンプレート特殊化に異な
る意味を与える場合,そのプログラムは,不適格とする。診断メッセージは必要としない。
(
候補関数
テンプレート仮引数に従属する関数呼出しにおいて,関数名が《修飾なし 識別子》であるが ,
《テンプレート識別子》でない場合,候補関数は,通常の検索規則(
及び
参照)を用いて見つけられる。
ただし ,次の例外をおく。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
―
修飾なし名の検索(
)を用いた検索では,そのテンプレート定義の文脈からの外部結合をもつ関数宣
言だけを見つけだす。
―
関連している名前空間を用いた検索(
)では,そのテンプレート定義の文脈 又は そのテンプレート
の具現化の文脈のいずれかの中にあって,外部結合をもつ関数宣言だけを見つけだす。
関連する名前空間内の検索において,そのテンプレート定義 及び テンプート具現化の文脈で見つかる宣言だけでな
く,外部結合をもって名前空間に導入された関数宣言すべてを,すべての翻訳単位で調べた場合に,その呼出しが不
適格となるか 又は より良い合致が見つかる場合,そのプログラムの動作は,未定義とする。
(#
クラステンプレート 内に宣言された随伴名
随伴クラス 又は 随伴関数は,クラステンプレート内に宣言で
きる。テンプレートが具現されるとき,その随伴クラス 又は 随伴関数の名前は,その特殊化がその具現化の位置で
明示的に宣言されたかのように扱われる。
非テンプレートのクラスと同様に,クラステンプレート特殊化の名前空間有効範囲の随伴関数の名前は,名前空間
有効範囲で明示的に宣言されていない限り,通常の検索で可視ではない(
参照)
。そのような名前は,関連する
クラスに対する規則(
)を使って見つかることもある
。
例
Q
&
''(((
0
0
Q
'!
(((
!'
R
''(((
R&
Q
*
M &
''(((
%
&
''
は,関連するクラスなので,
''
その名前空間( 広域有効範囲)で
が可視になり,
''
が見つかる
%
* M &
''
不適格
3
は,可視ではない
R
)
テンプレート の具現化 及び 特殊化
関数,クラス,クラステンプレートのメンバ 又は メンバテンプレート
を具現する処理をテンプレート具現化という。
関数テンプレートから具現された関数を具現された関数と呼ぶ。クラステンプレートから具現されたクラスを具現
されたクラスと呼ぶ。クラステンプレートのメンバ定義から具現されたクラステンプレートの,メンバ関数,メンバ
クラス 又は 静的データメンバを,それぞれ,具現されたメンバ関数,具現されたメンバクラス 又は 具現された静的
データメンバと呼ぶ。メンバ関数テンプレートから具現されたメンバ関数を具現されたメンバ関数と呼ぶ。メンバク
ラステンプレートから具現されたメンバクラスを具現されたメンバクラスと呼ぶ。
関数テンプレート,クラステンプレート,クラステンプレートのメンバ 又は メンバテンプレートに対して,明示的
な特殊化(テンプレート特殊化)を宣言してもよい。明示的な特殊化の宣言は,
で始める。クラステン
プレート,クラステンプレートのメンバ 又は クラスメンバテンプレートに対する明示的な特殊化( クラステンプレー
ト特殊化)の宣言では,明示的に特殊化されるクラスの名前は,
《テンプレート識別子》としなければならない。関数
テンプレート 又は メンバ関数テンプレートに対する明示的な特殊化( 関数テンプレート特殊化)の宣言では,明示
的に特殊化される関数 又は メンバ関数の名前は,
《テンプレート識別子》としてもよい。
例
%
6
Q
&
R&
G
G
Q
R
6
Q
R&
''
%%
で特殊化
6
Q
R&
''
%%
で特殊化
Q
R
''
G
%%
で特殊化
''
G
は,仮引数からの導出
Q
R
''
G
%%
で特殊化
633
%
.&
''
%%
で特殊化
注
随伴宣言は,テンプレートの宣言 又は 具現化のときに,どの有効範囲にも新しい名前を導入することはない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
%
"
Q
&
R&
"33
%
L&
''
%%
で特殊化
具現されたテンプレート特殊化には,明示的に具現(
)
)されたものと,実引数並びをもとに暗黙に具現(
)
)
されたものがある。特殊化とは,具現された,クラス,関数 若しくは クラスメンバ, 又は 明示的に特殊化(
)
)
された,クラス,関数 若しくは クラスメンバとする。
同じ《テンプレート実引数》に対して,次のことをしてはならない。
―
あるテンプレートを明示的に
回以上具現する。
―
あるテンプレートを明示的に具現し,かつ,明示的に特殊化する。
―
あるテンプレートを
回以上特殊化する。
この規則に違反しても,処理系は,診断メッセージを要求されない。
具現されたクラステンプレート特殊化のそれぞれは,静的メンバのコピーを個別にもつ。
例
5
Q
&
''
(((
R&
533
%
.&
5
&
5!
&
5
は,型
の静的メンバ
をもち,
5!
は,型
!
の静的メンバ
をもつ。
)
暗黙の具現化
クラステンプレート特殊化が,既に明示的に具現(
)
)されているか 又は 明示的に特殊
化(
)
)されている場合を除き,そのクラステンプレート特殊化が,完全に定義されたオブジェクト型を要求す
る文脈で使用されるか 又は そのクラス型の完全性がプログラムの意味に影響を与える場合,そのクラステンプレー
ト特殊化は,暗黙に具現される。クラステンプレート特殊化が暗黙に具現されることによって,そのクラスのメンバ
関数,メンバクラス,静的データメンバ 及び メンバテンプレートの宣言は,暗黙に具現される。しかし ,それらの
定義 又は 省略時実引数は,暗黙に具現されることはない。一方,そのメンバの無名の共用体の定義は,暗黙に具現
される。クラステンプレートのメンバ 又は メンバテンプレートが,既に明示的に具現されているか 又は 明示的に特
殊化されている場合を除き,その特殊化は,そのメンバ定義が要求される文脈で用いられたときに,暗黙に具現され
る。特に,静的データメンバの初期化(及び その副作用)は,定義が要求される方法でその静的データメンバが用い
られるまで,実行されない。
関数テンプレートの特殊化は,それが,既に明示的に具現されているか 又は 明示的に特殊化されている場合を除
き,その関数定義が要求される文脈で用いられたときに,暗黙に具現される。呼出しが,関数テンプレートの明示的
な特殊化 又は 明示的に特殊化されたクラステンプレートのメンバ関数に対するものでなければ ,関数テンプレート
又は クラステンプレートのメンバ関数のその関数をその省略時実引数は,その省略時実引数の値を必要とする文脈で
その関数を呼び出した時点で,暗黙に具現される。
例
K
Q
3
&
&
R&
Q
K
&
''
クラス
K
の具現化が要求される
K!
&
''
クラス
K
の具現化は,要求されない
K!
&
''
クラス
K
の具現化は,要求されない
( &
''
K33
の具現化が要求される
V &
''
クラス
K
の具現化が要求され,かつ
''
K33
の具現化も要求される
R
上の例では,クラス
K
,
K33
及び
K33
の暗黙の具現化は,要求されない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
クラステンプレート特殊化は,完全に定義されたオブジェクト型が要求される文脈でそのクラス型が使用されるか,
又は そのクラス型の完全性がプログラムの意味に影響を与える場合に,暗黙に具現される。特に,クラステンプレー
ト特殊化を型とする式が,多重定義解決,ポインタ変換 又は メンバへのポインタ変換に関わる場合,そのクラステ
ンプレート特殊化は,暗黙に具現される(
参照)
。さらに,
3
式の演算対象がクラス型 又は クラス型へのポ
インタで,かつ,そのクラス型がテンプレート特殊化の場合,そのクラステンプレート特殊化は,暗黙に具現される。
例
"
Q
'!
(((
!'
R&
#
3
"
Q
'!
(((
!'
R&
! &
"! &
#!
#!
#
Q
&
''
#
の具現化が要求される。
''
"!
の呼出し
"!
%
&
''
#
の具現化が要求される
''
#!
を
"!
へ変換
&
''
#
の具現化が要求される
R
多重定義解決において,クラステンプレート定義を具現することなく,呼び出すべき正しい関数が決定できる場合,
その具現化が実際に起こるか否かは,未規定とする。
例
F
Q
&
R&
&
F0 &
F &
F0
Q
&
''
F
の具現化は,許されているが要求されない
''
F
の具現化は,許されているが要求されない
R&
クラステンプレート特殊化の暗黙の具現化が要求され,そのテンプレートが宣言されていても定義されていない場
合,プログラムは,不適格とする。
例
5&
5
&
''
エラー
3
5
の定義が要求される
クラステンプレートの暗黙の具現化によって,そのクラスの静的データメンバが暗黙に具現されることはない。
関数テンプレート 又は メンバ関数テンプレートの特殊化が用いられ,それが多重定義解決を必要とする場合,そ
の特殊化の宣言は,暗黙に具現される(
参照)
。
クラステンプレートの,関数テンプレート,メンバテンプレート,非仮想メンバ関数,メンバクラス 又は 静的デー
タメンバの具現化が要求されない場合,処理系は,それらを暗黙に具現してはならない。クラステンプレートの仮想
メンバ関数に対して,その具現化が要求されず,それが暗黙に具現されない場合,それを処理系が暗黙に具現するか
否かは,未規定とする。省略時実引数の中にテンプレート特殊化を用いても,そのテンプレートが暗黙に具現される
ことはない。ただし,その省略時実引数の正当性を決定するために,そのクラステンプレートの完全型が必要とされ
るときには,その時点で暗黙に具現されることがある。関数呼出しにおいて省略時実引数が利用される場合,その省
略時実引数中の特殊化は,暗黙に具現される。
暗黙に具現された,クラステンプレート特殊化 及び 関数テンプレート特殊化は,そのテンプレートが定義された
名前空間に置かれる。暗黙に具現されたクラステンプレートのメンバの特殊化は,それを囲むクラステンプレートが
定義された名前空間に置かれる。暗黙に具現されたメンバテンプレートは,それを囲むクラス 又は クラステンプレー
トが定義された名前空間に置かれる。
例
A
Q
?
Q
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
3
!
&
''
(((
R&
R
>
H
@
Q
A33?H
&
H
> &
''
(((
R&
@!
0
Q
%
(YAY
&
''
(((
R
@! 33
から
(
を呼び出す場合,
?33
は,大域的名前空間で
はなく名前空間
A
に置かれる。
関数テンプレート
の呼出しで省略時実引数式が用いられる場合,その省略時実引数式で用いられたテンプレート
は,いずれも,あたかもその省略時実引数式が,その位置で用いられている関数テンプレート
と同じ有効範囲,同
じテンプレート仮引数,及び 同じアクセスをもつ関数テンプレート特殊化の中で用いられた式であるかのように,そ
の従属名が検索され,意味規則による制約が検査されて,具現される。この解析を,省略時実引数の具現化と呼ぶ。
具現された省略時実引数は,その後,
の実引数として用いられる。
例
それぞれの省略時実引数は,個別に具現される。
%
$
%
$ &
6
Q
R&
6
$6 &
6
6
6
Q
&
''
省略時実引数の具現化は,行われない
&
''
省略時実引数
$
%
$
が具現される
&
''
不適格
3
は,宣言されていない
R
参考
テンプレート特殊化の具現化の位置は,
(
で規定する。
再帰的な具現化の深さの合計に対する制限は,二つ以上のテンプレートを用いる場合を含め,処理系定義とする。
具現化が無限再帰となった場合の結果は,未定義とする。
例
5
Q
5!
&
''
B>
5!
&
''
5
の暗黙の具現化は,
''
5!
の暗黙の具現化を要求し ,それは,
''
5!!
の暗黙の具現化を要求し,それは,
(((
R&
)
明示的な具現化
クラス,関数 又は メンバテンプレート特殊化は,そのテンプレートから明示的に具現する
ことができる。クラステンプレートのメンバ関数,メンバクラス 又は 静的データメンバは,そのクラステンプレー
トの対応するメンバ定義から明示的に具現することができる。
明示的な具現化の構文は,次のとおりとする。
明示的具現化
3
宣言
明示的な具現化が,クラス,関数 又は メンバテンプレート特殊化の具現化の場合,その《宣言》中の《修飾なし識
別子》は,
《テンプレート識別子》とするか,
《テンプレート名》
(すべてのテンプレート実引数が導出し うる場合)と
しなければならない。
参考
その宣言は,
《修飾付き識別子》を宣言してもよい。その場合,
《修飾付き識別子》中の《修飾なし識別子》
は,
《テンプレート識別子》としなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
明示的な具現化が,クラステンプレート特殊化のメンバ関数,メンバクラス 又は 静的データメンバの具現化の場合,
《修飾付き識別子》中のクラステンプレート特殊化の名前は,
《テンプレート識別子》としなければならない。
例
6
Q
&
R&
6&
633
&
60
Q
'!
(((
!'
R
6
0 &
''
実引数は,ここで導出される
A
Q
0
Q
R
R
A330 &
関数テンプレートの宣言は,その関数テンプレートの明示的な具現化の位置で有効でなければならない。メンバ関
数テンプレートを含んでいるクラス 又は クラステンプレートの定義は,そのメンバ関数テンプレートの明示的な具
現化の位置で有効でなければならない。クラステンプレート 又は クラスメンバテンプレートの定義は,そのクラステ
ンプレート 又は クラスメンバテンプレートの明示的な具現化の位置で有効でなければならない。クラステンプレー
トの定義は,そのクラステンプレートのメンバ関数 又は 静的データメンバの明示的な具現化の位置で有効でなけれ
ばならない。クラステンプレートのメンバクラスの定義は,そのメンバクラスの明示的な具現化の位置で有効でなけ
ればならない。明示的な具現化の《宣言》が暗黙に宣言された特別なメンバ関数(
)を宣言する場合,そのプロ
グラムは,不適格とする。
移出されていない関数テンプレート,移出されていないメンバ関数テンプレート 又は クラステンプレートの移出
されていないメンバ関数 若しくは 静的データメンバの定義は,それが明示的に具現される各翻訳単位ごとに存在し
なければならない。
クラステンプレート 又は 関数テンプレートの特殊化の明示的な具現化は,そのテンプレートが定義された名前空
間に置かれる。クラステンプレートのメンバの明示的な具現化は,それを囲むクラステンプレートが定義された名前
空間に置かれる。メンバテンプレートの明示的な具現化は,それを囲むクラス 又は クラステンプレートが定義され
た名前空間に置かれる。
例
A
Q
J
Q
Q
R
R&
R
J&
''
エラー
3
クラステンプレート
J
は,
''
大域的名前空間で可視でない
A33J&
J&
''
B>3
名前空間
A
における明示的な具現化
A33J!&
''
B>3
名前空間
A
における明示的な具現化
A33J33
&
''
B>3
名前空間
A
における明示的な具現化
関数テンプレート特殊化 又は メンバ関数テンプレート特殊化の明示的な具現化において,名前の後に指定する《テ
ンプレート実引数》は,それがその関数の仮引数の型から導出できる場合,指定しなくともよい(
参照)
。
例
6
Q
'!
(((
!'
R&
60
&
''
6
0
を具現
V
テンプレート実引数は,導出できる
6
0
&
クラステンプレート特殊化の明示的な具現化によって,その明示的な具現化を含む翻訳単位の中で,それより前に
は明示的に特殊化されていないメンバすべてが,具現される。
明示的な具現化を指定するために用いる名前には,通常のアクセス検査規則は,適用されない。
参考
特に,関数宣言子( 仮引数型,返却値の型 及び 例外仕様を含む。)中で使用される名前は,通常はアク
セス可能でない非公開の型 又は オブジェクトであってもよい。また,そのテンプレートは,通常はアク
セス可能でないメンバテンプレート 又は メンバ関数であってもよい。
明示的な具現化では,省略時実引数は使用されない。省略時実引数の具現化も行われない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
!
%
.&
%
0 &
&
''
0
が
でないとしても
B>
)
明示的な特殊化
次のテンプレートの明示的な特殊化は,いずれも
ではじまる宣言で宣言する
ことができる。
―
関数テンプレート
―
クラステンプレート
―
クラステンプレートのメンバ関数
―
クラステンプレートの静的データメンバ
―
クラステンプレートのメンバクラス
―
クラステンプレートのメンバクラステンプレート
―
クラステンプレートのメンバ関数テンプレート
すなわち,次の構文で宣言する。
明示的特殊化
3
宣言
例
&
Q
'!
(((
!'
R&
6
Q
'!
(((
!'
R&
60
Q
'!
(((
!'
R
!6
!
0
&
これらの宣言が与えられたとする。
のストリームの定義には,
が使用される。その
他のストリームは,クラステンプレートから具現されるクラステンプレートの特殊化によって扱われる。
同様に,
6!
型の実引数に対するソート 関数として,
!
が使用される。その他の
6
型は,テンプレートから生成される関数によってソートされる。
明示的な特殊化は,そのテンプレートが属している名前空間で宣言しなければならない。そのテンプレートが メン
バテンプレートの場合,それを囲むクラス 又は クラステンプレートが属している名前空間で宣言しなければならな
い。クラステンプレートのメンバ関数,メンバクラス 又は 静的データメンバの明示的な特殊化は,そのクラステン
プレートが属している名前空間で宣言しなければならない。これらの宣言は,定義であってもよい。宣言が定義でな
い場合,その明示的な特殊化が宣言された名前空間の中,又は その明示的な特殊化が宣言された名前空間を囲む名前
空間の中で,その特殊化を後で定義することができる。
関数テンプレート 又は クラステンプレートを明示的に特殊化する場合,その宣言は,その明示的な特殊化の宣言
位置で有効でなければならない。
参考
要求されるのは,テンプレートの定義ではなく,宣言である。
クラス 又は クラステンプレートの定義は,そのクラスのメンバテンプレート 又は クラステンプレートを明示的に特
殊化する場合,その明示的な特殊化の宣言位置で有効でなければならない。
例
5
Q
'!
(((
!'
R&
''
エラー
3
5
はテンプレートでない
5&
5!
Q
'!
(((
!'
R&
''
B>3
5
はテンプレート
暗黙に具現されたクラス特殊化に対して,そのクラステンプレートのメンバ関数,メンバクラス 又は 静的データ
メンバを明示的に特殊化してもよい。その場合,そのクラステンプレートの定義は,クラステンプレートのメンバの
明示的な特殊化の宣言位置で有効でなければならない。そのようなクラステンプレートのメンバの明示的な特殊化が,
暗黙に宣言された特別なメンバ関数(
)の場合,そのプログラムは,不適格とする。
明示的に特殊化されたクラスのメンバが,そのクラステンプレートのメンバ宣言から暗黙に具現されることはない。
クラステンプレート特殊化のメンバは,明示的に定義しなければならない。その場合,クラステンプレートの明示的
な特殊化の定義は,そのメンバの明示的な特殊化の宣言位置で有効でなければならない。明示的に特殊化されたクラ
スの定義は,生成された特殊化の定義とは無関係とする。すなわち,その メンバは,生成された特殊化と同じ 名前,
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
型などをもつ必要はない。明示的に特殊化されたクラスのメンバの定義は,通常のクラスのメンバと同様の方式で行
ない,明示的な特殊化の構文は用いない。
例
6
Q
Q
'!
(((
!'
R
R&
6
Q
&
R&
Q
6
&
(L- &
''
633
は,どこかで定義しなければならない
R
''
明示的な特殊化の構文は,明示的に特殊化したクラステンプレート特殊化の
''
メンバには用いない
633
Q
'!
(((
!'
R
テンプレート,メンバテンプレート 又は クラステンプレートのメンバを明示的に特殊化する場合,その特殊化は,
すべての翻訳単位で,その特殊化を暗黙に具現する使用の前に宣言しなければならない。プログラムが明示的な特殊
化の定義を与えず,その特殊化が暗黙に具現される方法で使用されるか 又は その特殊化されたメンバが仮想メンバ
関数の場合,そのプログラムは,不適格とする。診断メッセージは必要としない。宣言されているが定義されていな
い明示的な特殊化が,暗黙に具現されることはない。
例
6
Q
'!
(((
!'
R&
60
Q
'!
(((
!'
R
6F0
Q
&
''
一次テンプレートを用いる
''
60
は
F
R
F6
F
0
&
''
エラー
3
一次テンプレートの
''
使用の後の特殊化
6
!
0
&
''
B>3
!
は,まだ
''
使用されていない
関数テンプレート,クラステンプレート,クラステンプレートのメンバ関数,クラステンプレートの静的データメ
ンバ,クラステンプレートのメンバクラス,クラステンプレートのメンバクラステンプレート,クラステンプレート
のメンバ関数テンプレート,クラステンプレートのメンバテンプレートのメンバ関数,非テンプレートのクラスのメ
ンバテンプレートのメンバ関数,クラステンプレートのメンバクラスのメンバ関数テンプレートなどに対する明示的
特殊化宣言の場所,及び クラステンプレート,非テンプレートのクラスのメンバクラステンプレート,クラステンプ
レートのメンバクラステンプレートなどに対する部分特殊化宣言の場所は,
)
の規定に従い,翻訳単位内での明
示的特殊化宣言の相対的な位置 及び それらの特殊化の位置によって,プログラムが不適格か否かに影響を与えうる。
特殊化を宣言する場合には,コンパイル時にエラーとなることを避けるため,その位置に注意しなければならない。
特殊化が,移出されたテンプレートの具現化で用いられ,その特殊化されていないテンプレート名が移出されたテ
ンプレートの中で非従属であり,かつ,明示的な特殊化が存在している場合,その明示的な特殊化は,移出されたテ
ンプレートの定義を含む翻訳単位の中で,その定義より前に宣言しなければならない。
例
''
ファイル
L
''
一次クラステンプレート
Q
33
&
''
特殊化と合致しなければなならない
'!
(((
!'
R
''
ファイル
+
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
"
Q
R&
''
"
の明示的な特殊化
Q
"
Q
'!
(((
!'
R&
R
&
"
Q
&
''
不適格
3
''
"
は,
"
を参照する
''
しかし ,その特殊化は,
の定義が含まれる
''
ファイル
L
で宣言されていない
R
テンプレートの明示的な特殊化は,そのテンプレートが定義された名前空間の有効範囲に書かなければならない。
例
A
Q
5
Q
'!
(((
!'
R&
J
Q
'!
(((
!'
R&
5
Q
'!
(((
!'
R&
''
B>3
同じ名前空間にある
''
特殊化
J&
''
に対する特殊化を
''
意図している先行宣言
R
A33J
Q
'!
(((
!'
R&
''
B>3
同じ名前空間にある
''
特殊化
宣言されているが定義されていないクラステンプレートの明示的な特殊化を名付ける《テンプレート 識別子》は,
他の不完全に定義されたクラスの名前(
*
)と同様に使用できる。
例
5&
''
5
はクラステンプレート
5&
5!
&
''
B>3
宣言されたクラス
5
へのポインタ
5
&
''
エラー
3
不完全クラス
5
のオブジェクト
明示的な関数テンプレート特殊化を名付ける《テンプレート識別子》において,名前に続く《テンプレート実引数》
は,それがその関数の実引数の型から導出できる場合には,指定しなくてもよい。
例
6
Q
'!
(((
!'
R&
60
&
''
6
0
の明示的特殊化
''
型
は,テンプレート実引数から導出できるので次のように書いてもよい
60
&
参考
この節は,
+"-6666
によって削除された。
ある関数が,あるテンプレートと同じ名前をもち,かつ,そのテンプレートのある特殊化の型と厳密に合致する型
をもっていたとしても,それは,そのテンプレートの明示的な特殊化ではない(
##
参照)
。
関数テンプレートの明示的な特殊化は,その特殊化を明示的にインラインと宣言した場合にだけ,インライン関数
となる。その関数テンプレートが インラインと宣言されているか否かは,特殊化がインラインとなるかならないかに
は影響しない。
例
Q
'!
(((
!'
R
Q
'!
(((
!'
R
Q
'!
(((
!'
R
''
B>3
インライン
Q
'!
(((
!'
R
''
B>3
インラインではない
テンプレートの静的データメンバの明示的な特殊化は,その宣言が初期化子を含む場合,定義とする。そうでない
場合,宣言とする。
参考
省略時の初期化を要求する,テンプレートの静的データメンバの定義を与える構文は,存在しない。
5
D33&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
この例は,
5
が省略時初期化(
#
)できるか否かとは無関係に,宣言となる。
クラステンプレートのメンバ 又は メンバテンプレートは,そのクラステンプレートの暗黙の具現化に対して,明
示的に特殊化してよい。これは,そのクラステンプレート定義の中で定義されている場合であっても,許される。メ
ンバ 又は メンバテンプレートの明示的な特殊化には,テンプレート特殊化の構文を用いる。
例
6
Q
&
5L
L 5L &
5+
+ 5+ &
Q
R
R&
''
特殊化
633 &
''
外側でのクラスメンバテンプレート定義
5L
633L 5L
Q
R
''
メンバテンプレートの特殊化
5L
633L 5L
&
''
メンバテンプレートの特殊化
633L
&
''
5L
は,
と導出
633+
&
''
5+
は,
と指定
''
クラス定義で定義されていても,メンバを特殊化できる
633
Q
R
メンバ 又は メンバテンプレートは,それを囲む複数のクラステンプレートの中に入れ子になっていることがある。
そのようなメンバに対する明示的特殊化の宣言が名前空間有効範囲に現れる場合,そのメンバ宣言の前には,明示的
に特殊化される囲んでいるクラステンプレートのそれぞれに対して,一つずつ
を置かなければならない。
例
L
6
Q
+
"
Q
&
R&
R&
633"
&
633"
33
&
名前空間有効範囲におけるメンバテンプレート 又は クラステンプレートのメンバの明示的な特殊化の宣言では,メ
ンバテンプレート 及び それを囲むクラステンプレートの一部を特殊化しなくともよい。ただし ,外側のクラステン
プレートを明示的に特殊化せずに,それに囲まれたクラスメンバテンプレートを明示的に特殊化してはならない。こ
うした明示的な特殊化宣言では,メンバの明示的な特殊化宣言の場合に前置される
の代わりに,
《テンプ
レート仮引数並び》が続くキーワード
を用いなければならない。
《テンプレート 仮引数並び》中のテンプ
レート仮引数の型は,一次テンプレート定義で指定した型と同一でなければなければならない。
例
L
6
Q
+
"
Q
*
L* &
+ &
R&
R&
5
633"
Q
R
633"
33
L
Q
R
J
6J33"33
+
Q
R
''
不適格。
"
は特殊化されているが,
''
それを囲むクラステンプレート
6
が特殊化されていない
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
特殊化されていないクラステンプレートの,メンバ関数テンプレートの特殊化 又は メンバクラステンプレートの
特殊化は,それ自身テンプレートとなる。
明示的な特殊化宣言は,随伴宣言としてはならない。
関数の省略時実引数は,次の明示的特殊化の宣言 又は 定義の中で指定してはならない。
―
関数テンプレートの明示的な特殊化
―
メンバ関数テンプレートの明示的な特殊化
―
クラステンプレートのメンバ関数の明示的な特殊化。ただし ,そのメンバ関数の特殊化が属しているクラ
ステンプレートの特殊化が暗黙に具現される場合に限る。
参考
関数の省略時実引数は,明示的に特殊化されたクラステンプレート特殊化のメンバ関数の宣
言 又は 定義では指定してもよい。
関数テンプレート の特殊化
関数テンプレートから具現された関数を,関数テンプレート特殊化と呼ぶ。関数
テンプレートの明示的な特殊化も,関数テンプレート特殊化と呼ぶ。テンプレートの実引数は,関数テンプレート特
殊化を指定するときに明示的に指定することができるが,そうしなかった場合は,その文脈( 例えば,関数テンプレー
ト特殊化の呼出しにおける関数実引数)から導出(
)される。
テンプレートから具現された関数テンプレート特殊化は,それぞれが,静的変数のコピーを個別にもつ。
例
!
Q
&
''
(((
R&
!
Q
0 &
''
!
の呼出し
0 &
''
!!!
の呼出し
R
!
は,型
の静的変数
をもち,
!!!
は,型
!
の静的変数
をもつ。
テンプレート 実引数の明示的な指定
関数テンプレート特殊化を参照する場合,クラステンプレート特殊化
への《テンプレート実引数》の指定と同じ方法で,関数テンプレート名を《テンプレート実引数》並びで修飾するこ
とによって,テンプレート実引数を指定することができる。
例
60
&
6
0
60
Q
&
''
6
0
&
''
60
R
G
H
G
H
&
Q
%
&
''
%
&
''
R
テンプレート実引数並びは,関数テンプレート特殊化を参照する次の場合に指定してもよい。
―
関数を呼び出す場合
―
関数のアドレスを得る場合,関数が関数への参照を初期化する場合 又は メンバ関数へのポインタを形成
する場合
―
明示的な特殊化の中
―
明示的な具現化の中
―
随伴宣言の中
残りのテンプレート実引数は,それが導出可能な(
)場合,明示的な《テンプレート実引数》の並びから省略
してもよい。すべてのテンプレート実引数が導出可能な場合,それらすべてを省略してもよい。その場合,空のテン
プレート実引数並び
も省略することができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
例
5
J
5
J &
Q
%
/(- &
''
J
は,
と導出される。
%
/(- &
''
不正
3
5
は,導出できない
R
参考
通常の( すなわち,テンプレートでない)関数が可視であって,何も指定しなければ ,それが利用され
る場合,関数テンプレート特殊化を参照するために,空のテンプレート実引数並びを用いることができる。
例
&
''
L
&
''
+
%
L &
''
+
を用いる
%
L &
''
L
を用いる
テンプレート実引数は,対応する《テンプレート仮引数》の宣言順に指定しなければならない。テンプレート実引
数並びに,対応する《テンプレート仮引数》の数より多くの《テンプレート実引数》を指定してはならない。
例
5
J
K
5
J K &
Q
!
Y
Y
*(
.
&
!YY
*(
.
&
''
K
は,
に導出される
YY *(. &
''
J
は,
!
に導出され
''
K
は,
に導出される
YY *(. &
''
エラー
3
5
は,導出できない
R
関数の仮引数の型に,テンプレート実引数の導出に関係する《テンプレート仮引数》が含まれない場合,実引数を
対応する仮引数の型に変換するため,暗黙の変換(
)が行われる。
参考
テンプレート仮引数は,それらを明示的に指定した場合,テンプレート実引数の導出には関係しない。
&
7
Q
''
(((
7 &
R&
Q
7L &
''
B>3
77
L
を意味する
R
参考
明示的なテンプレート実引数並びは,関数テンプレート名に続けて記述する。一方,変換メンバ関数テ
ンプレート 及び コンストラクタメンバ関数テンプレートは,関数名を使用せずに呼び出される。したがっ
て,これらの関数テンプレートに対して,明示的なテンプレート実引数並びを与える方法は存在しない。
参考
単純な関数名に対しては,その関数名が呼出しの時点で可視でない場合であっても,実引数依存の名前
検索(
)が適用される。その理由は,この場合にも,その呼出しが関数呼出しの構文形式(
)
となるためである。しかし,明示的なテンプレート実引数を伴う関数テンプレートの場合,その呼出し位
置で名前が可視な関数テンプレートが存在しなければ ,その呼出しは,適格な構文形式とはならない。し
たがって,テンプレートの名前が可視でない場合,その呼出しは,構文的に適格でなく,実引数依存の名
前検索は適用されない。テンプレートの名前が可視の場合,実引数依存の名前検索が適用され,追加の関
数テンプレートが別の名前空間で見つかることもある。
例
6
Q
"
Q
R&
5
" &
R
7
Q
&
R
633"
Q
* &
''
不適格
3
関数呼出しではない
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
633* &
''
適格
733* &
''
不適格
3
実引数依存の検索は,
''
修飾されない名前にだけ適用される
733&
* &
''
733
が可視なため適格。次に
''
633
が実引数依存の検索で見つかる
R
テンプレート 実引数の導出
関数テンプレートの特殊化を用いる場合,すべてのテンプレート実引数は,値
をもたなければならない。その値は,明示的に指定してもよいが,そうしなければ ,その使用から導出される。
例
6
0
60
Q
&
''
6
0
の呼出し
&
''
60
の呼出し
R
及び
Q
%
&
''
の呼出し
%
&
''
の呼出し
R
テンプレート実引数並びが明示的に指定された場合,そのテンプレート実引数は,テンプレート仮引数並びと適合
しなければならず,また,この節に規定するとおり,正当な関数型を導くものでなければならない。そうでない場合,
型導出は,失敗とする。すなわち,ある関数テンプレートに対して,明示的に指定されたテンプレート実引数並びは,
次の手順で評価される。
―
指定されたテンプレート実引数は,テンプレート仮引数と同じ種類(すなわち,型,非型 及び テンプレー
ト )でなければならない。そうでない場合,型導出は,失敗とする。
―
非型の実引数は,対応する非型のテンプレート仮引数の型に合致するか,又は
の規定に従い,対
応する非型の仮引数に変換可能でなければならない。そうでない場合,型導出は,失敗とする。
―
関数テンプレートの関数型の中で,テンプレート仮引数を参照している場合,その参照はすべて,対応す
る指定されたテンプレート実引数の値で置き換えられる。テンプレート仮引数の中 又は 関数テンプレー
トの関数型の中でのこの置換の結果が無効な型になる場合,型導出は,失敗とする。
参考
例外指定における同様な置換は,関数が具現された場合にだけ行われる。その置換の結果が
無効な型になる場合,プログラムは,その具現化の位置で不適格となる。
型導出は,次のいずれかの場合にも失敗する。
―
要素の型が
0
3
,関数型 若し くは 参照型の配列を生成する 又は要素の型が大きさがゼロ 若
しくは 負の配列を生成する場合
例
S/T &
<
%
. &
%
. &
''
誤り
3
無効な配列
―
修飾付き名前に,クラス型ではない型を用いた場合
例
33"! &
%
. &
''
誤り
―
修飾付き名前の型を示す修飾部分に,指定されたメンバを含んでいない型を用いた場合,又は
指定されたメンバが型であるべきときにそのメンバが型でない場合
例
33"! &
6
QR&
7
Q
"&
R&
%
6. &
''
誤り
%
7. &
''
誤り
―
参照型へのポインタを生成する場合
―
参照型への参照 又は
0
3
への参照を生成する場合
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
―
型
がクラス型でない場合に,
:
のメンバへのポインタ
;
を生成する場合
例
33! &
%
. &
''
誤り
―
テンプレート実引数式 又は 関数宣言で用いられる式において,無効な変換を実行する場合
例
!
&
+
%
L. &
''
誤り
3
L
を
!
へ変換できない
―
0
3
型の仮引数をもつ関数型を生成する場合
―
0
修飾された関数型を生成する場合
この置換が行なわれた後,
#
で規定した関数仮引数の型の調整が行われる。
例
:
S/T ;
の仮引数型は,
:!
!
;
になる。
参考
関数仮引数宣言の最上位の修飾子は,関数型に影響しないが,その関数中の関数仮引数変数の型には依
然として影響する。
例
&
5
5
&
K
K
K! &
Q
''
L3
関数型は,
であり
は,定値でない
L &
''
+3
関数型は,
であり
は,定値である
L &
''
*3
関数型は,
は,定値である
L &
''
M3
関数型は,
は,定値である
L &
''
/3
関数型は,
!
である
L . &
R
参考
L
及び
L
は,同じ関数型の関数を呼び出すが,それらは,異なる関数である。
置換 及び 調整が行なわれた結果の関数型は,テンプレート実引数導出の関数テンプレートの型として用いられる。
すべてのテンプレート実引数が導出された後,導出の対象外の文脈にあるすべてのテンプレート仮引数の使用が,対
応する導出された実引数の値で置き換えられる。その置換の結果,ここまでの規定に従って,無効な型が生成される
場合,型導出は,失敗する。
上で規定したことを除けば ,無効な値を用いることが型導出の失敗する原因になることはない。
例
次の例において,
L...
は,
に変換され,
)
で規定する処理系定義の値になる。さらに言え
ば ,
L...
が,
に変換される場合,処理系定義の値になるとしても,両方のテンプレートが
考慮される。
&
&
L
%
L. &
''
あいまい
+
%
L.... &
''
あいまい
関数呼出しによるテンプレート 実引数の導出
関数呼出しの場合,テンプレート実引数の導出は,各関数
テンプレートの仮引数の型(
とする)とそれに対応する実引数の型(
とする)とを,次の規定に従って比較する
ことによって行われる。
が参照型でない場合,型導出では次のとおりとする。
―
が配列型の場合,
の代わりに,配列からポインタへの標準変換(
)を適用した型が用いられる。
―
が関数型の場合,
の代わりに,関数からポインタへの標準変換(
)を適用した型が用いられる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
―
が配列型でも関数型でもなくて,
が
0
修飾された型の場合,
の型の最上位の
0
修飾子は,無視さ
れる。
が
0
修飾された型の場合,
の型の最上位の
0
修飾子は,型導出では無視される。
が参照型の場合,
が参照
する型が型導出に用いられる。
型導出の処理は,導出された
が( 型
が上記の変換を受けた後の )
と一致するようなテンプレート実引数の
値を見付けようとする。しかし,次の三つの場合には一致しなくともよい。
―
元の
が参照型の場合,導出された
( すなわち,その参照で参照する型)は,
より多く
0
修飾され
ていてもよい。
―
は,修飾変換(
)によって,導出された
に変換できる別のポインタ型 又は メンバへのポインタ型
であってもよい。
―
がクラスであって,
《テンプレート識別子》の形式の場合,
は,導出された
の派生クラスであっても
よい。同様に,
が《テンプレート識別子》形式のクラスへのポインタの場合,
は,導出された
に指
される派生クラスへのポインタであってもよい。
これらの選択肢は,これらが選ばれなければ型導出が失敗する場合にだけ考慮される。これらが複数の
を導出し う
る場合,型導出は,失敗とする。
参考
《テンプレート仮引数》が,関数テンプレートの関数仮引数に用いられない場合 又は 導出以外の文脈
でだけ用いられる場合,それに対応する《テンプレート実引数》は,関数呼出しからは導出できないから,
《テンプレート実引数》を明示的に指定しなくてはならない。
関数テンプレート のアドレスを得る場合のテンプレート 実引数の導出
テンプレート実引数は,多重定義
された関数(
)のアドレスを得る際に,その関数に指定された型から,導出することができる。関数テンプレー
トの関数型 及び その指定された型は,それぞれ
及び
の型として用いられ,
の規定に従って導出が行
なわれる。
変換関数テンプレート の実引数の導出
変換関数の場合,テンプレート実引数の導出は,
の規定
に従って,テンプレート 変換関数の返却値の型(
とする。)を,変換の結果の型(
とする。)と比較することに
よって行われる。
が参照型でない場合,型導出では,次のとおりとする。
―
が配列型の場合,
の代わりに,配列からポインタへの標準変換(
)を適用した型が用いられる。
―
が関数型の場合,
の代わりに,関数からポインタへの標準変換(
)を適用した型が用いられる。
―
が配列型でも関数型でもなくて,
が
0
修飾された型の場合,
の型の最上位の
0
修飾子は,無視さ
れる。
が
0
修飾された型の場合,
の型の最上位の
0
修飾子は,型導出では,無視される。
が参照型の場合,
が参
照する型が型導出に用いられる。
導出処理は,導出された
が
と一致するテンプレート実引数の値を見付けようとする。しかし ,次の二つの場
合には一致しなくともよい。
―
元の
が参照型の場合,
は,導出された
(すなわち,その参照で参照されている型)より多く
0
修
飾されていてもよい。
―
導出された
は,修飾変換によって,
に変換され うる別の,ポインタ型 又は メンバへのポインタ型で
あってもよい。
これらの選択肢は,これらが選ばれなければ型導出が失敗する場合にだけ対象とする。これらが複数の
を導出し う
る場合,型導出は,失敗とする。
型からのテンプレート 実引数の導出
テンプレート実引数は,異なる文脈で導出され うる。しかし ,どの
場合も,テンプレート仮引数に指定された型(
とする。)と実際の型(
とする。)とが比較され,
と
が,導出
された値( 導出された
と呼ぶ。)で置換することによって互換となるようなテンプレート実引数の値( 型仮引数で
は型,非型仮引数では値,テンプレート仮引数ではテンプレートとなる。)を見付ける試みが行われる。
導出では,型
と型
の一つの対が用いられる場合も,型
と型
の複数の対が用いられる場合もある。型導出
は,
と
の対それぞれに対して別々に行われ,その後,導出されたテンプレート実引数の値が結合される。ど の
と
の対に対しても型導出が失敗する場合,いずれかの対が導出値の集合を複数生ずる可能性がある場合,異なる
対が異なる導出値を生ずる場合,又は いずれかのテンプレート実引数が導出されず,明示的な指定もないまま残る場
合,テンプレート実引数の導出は,失敗とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
型
は,複数の異なる型,テンプレート 及び 非型の値から構成され うる。
―
関数型は,関数の仮引数 及び 返却値の型を含む。
―
メンバへのポインタ型は,それが指しているクラスオブジェクトの型 及び それが指しているメンバの型
を含む。
―
クラステンプレートの特殊化の型( 例えば
)は,その特殊化のテンプレート実引数並びによって
参照される,型,テンプレート 及び 非型の値を含む。
―
配列型は,配列要素の型 及び 配列の範囲を示す値を含む。
を構成する型,テンプレート 及び 非型の値は,ほとんどの場合,テンプレート実引数の導出に関係している。す
なわち,それらは,テンプレート実引数の値を決定するために使用され うるし ,決定された値は,その他の場所で決
定された値と整合していなければならない。しかし ,ある文脈では,その値は型導出に関係せず,その代わり,別の
場所で導出された 又は 明示的に指定されたテンプレート実引数の値が用いられる。テンプレート仮引数が,導出の
対象外の文脈でだけ用いられ,明示的に指定されない場合,テンプレート実引数の導出は,失敗とする。
導出の対象外の文脈は,次のとおりとする。
―
《修飾付き識別子》に指定された,型を示す《入れ子名前指定子》
―
《テンプレート識別子》の形をした型であって,その《テンプレート実引数》の少なくとも一つが《テン
プレート仮引数》を参照した式の形となっているもの
型名を,導出の対象外の文脈を含む形で指定した場合,その型名を構成する型名すべてが導出されない。しかし,複
合型は,導出される型 及び 導出されない型の両方を含むことができる。
例
型を
633"+
と指定した場合,
及び
+
は,ど ちらも導出されない。同様に,型を
6<)=335
と指定した場合,
<
,
=
及び
は,導出されない。型を
633"
6
と指定した
場合,
633"
中の
は,導出されないが,
6
中の
は,導出される。
例
仮引数と実引数との複数の対が,整合性のないテンプレート実引数を導出する例を示す。
Q
'!
(((
!'
R
6
Q
'!
(((
!'
R&
"
3
6
Q
'!
(((
!'
R&
6
"
Q
&
''
エラー
3
は,
6
でも
"
でもよい
&
''
エラー
3
は,
6
でも
"
でもよい
&
''
B>3
は,
6
&
''
B>3
は,
"
R
関数の仮引数と実引数の一つの対から,二つのテンプレート実引数が導出される例を示す。これらは競
合する可能性があり,その場合,型導出は,失敗となる。
G
!
G
G
&
L
&
+
&
*
&
Q
L &
''
B>3
は,
で,
G
は,
+ &
''
エラー
3
は,
でも
でもよい
* &
''
エラー
3
G
は,
でも
でもよい
R
関数呼出しの実引数の型と導出されたテンプレート実引数の型の間で,修飾変換が行なわれる例を示す。
!
QR
!&
Q
&
''
!
R
テンプレート実引数が,それに対応する関数仮引数型の派生クラス型を具現するために用いられる例を
示す。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
"
Q
R&
#
3
"
QR&
#+
3
"
QR&
"0 QR
Q
#
&
#+
+&
&
''
"0
を呼び出す
+ &
''
"0
を呼び出す
R
テンプレートの型実引数
,テンプレートのテンプレート実引数
又はテンプレートの非型実引数
は,
及び
が,次のいずれかの形式の場合,導出できる。
修飾子列
!
0
S
整数定数
T
テンプレート名
(テンプレート名は,クラステンプレートを参照する)
型
!
!
!
型
33!
型
33!
33!
型
33!
型
33!
型
型
33!
型
33!
型
33!
33!
33!
型
ST
テンプレート名
(テンプレート名は,クラステンプレートを参照する)
ここで,
は,少なくとも一つの実引数型が
を含む実引数並びを示し ,
は,どの実引数も
を含まない実引
数並びを示す。同様に,
は,少なくとも一つの実引数が
を含むテンプレート実引数並びを示し,
は,少な
くとも一つの実引数が
を含むテンプレート実引数並びを示し,
は,実引数が
も
も含まないテンプレート実引
数並びを示す。
これらの形式は,
を型の複合化に用いるのと同様の方法で,用いることができる。
例
次の例で,
行目のプログラムは,
行目の形式をもち,それは,
行目の変形である。
5
! S-T
テンプレート名
!
型
ST
型
!
5
は
:
型
;
に対応し ,
S-T
が
に対応する。
テンプレート実引数は,ここまでに規定した構成要素以外の関数実引数から,導出することはできない。
テンプレートの型実引数は,非型の《テンプレート実引数》から導出することはできない。
例
SL.TST &
SL.TS+.T&
&
''
エラー
3
テンプレート仮引数
の実引数は,導出できない
参考
参照型 及び ポインタ型に含まれる場合を除き,配列の主範囲は,関数仮引数の型の一部ではなく,実
引数から導出できない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
L
SL.TST &
+
STS+.T &
*
0 STS+.T &
Q
SL.TS+.T&
L &
''
B>3
は,
+.
に導出される
L+. &
''
B>
+ &
''
エラー
3
テンプレート実引数
を導出できない
+L. &
''
B>
* &
''
B>3
は,
L.
に導出される
R
非型の《テンプレート仮引数》をもつ関数テンプレートの宣言において,関数の《仮引数並び》の中の
式として,非型の《テンプレート仮引数》を用いる場合,それに対応する《テンプレート実引数》は,ど
こか別の場所で明示的に指定するか 又は 導出されなければならない。そうでない場合,その《テンプレー
ト実引数》に対する型導出は,常に失敗する。
6
Q
'!
(((
!'
R&
6)L &
Q
6L
&
&
''
エラー
3
式
)L
に対して導出が失敗
. &
''
B>
R
参考
テンプレート仮引数は,導出の対象外の文脈でだけ用いられる場合,テンプレート実引数の導出に関係
しない。例を示す。
6335
''
は,ここでは導出されない
''
しかし ,
は,ここでは導出される
"33J
&
''
は,ここでは導出されない
6
&
",,
&
%
,,(
-+
( &
''
は,
に導出される。
(
は
6335
に変換可能でなければならない
''
は,明示的に
,,
に指定されている。
(
は,
",,33J
に変換可能でなければならない
非型の《テンプレート仮引数》をもつ関数テンプレートの宣言において,非型の《テンプレート仮引数》が関数の
《仮引数並び》の中の式として用いられ,それに対応する《テンプレート 実引数》が導出される場合,その《テンプ
レート実引数》の型は,
《テンプレート仮引数》の型に正確に合致しなければならない。ただし ,
《テンプレート 実引
数》が配列範囲から導出された場合,その型は汎整数型のどれであってもよい
。
例
6
Q
'!
(((
!'
R&
6 &
L
Q
6L
&
&
''
エラー
3
から
への変換の導出が失敗する
L &
''
B>
R
"
Q
R&
" &
+
Q
"L
&
&
''
B>3
修飾子は,テンプレート仮引数型では無視される
R
関数へのポインタ 又は メンバ関数へのポインタの実引数から導出できるのは,
《テンプレート実引数》が多重定義
された関数の集合が関数テンプレートを含まず,高々一つの多重定義関数が合致する場合とする。
注
型の《テンプレート仮引数》に対する《テンプレート実引数》が配列範囲から導出されてもよい。しかし ,配列範囲は非ゼロで
あることから,その結果の値は,常に
$
となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例
!
&
&
&
&
&
&
Q
0 &
''
エラー
3
あいまい
0 &
''
B>3
は,唯一の合致
0 &
''
エラー
3
がテンプレートなので型導出は,失敗する
R
テンプレートの《型仮引数》は,関数の省略時実引数の型からは導出できない。
例
%
/
%
, &
Q
L &
''
B>3
L ,
を呼び出す
&
''
エラー
3
を導出できない
&
''
B>3
/ ,
を呼び出す
R
テンプレートの《テンプレート仮引数》に対応する《テンプレート実引数》は,関数呼出しの実引数並びで用いら
れるクラステンプレートの特殊化の《テンプレート実引数》の型から,導出される。
例
5
6
Q
R&
5
65
Q
R
"
Q
R&
6"
&
&
''
6"
を呼び出す
参考
関数テンプレートの宣言 又は 定義に,省略時の《テンプレート実引数》は,指定できない。したがっ
て,省略時の《テンプレート実引数》は,テンプレート実引数の導出に影響を与えない。
多重定義解決
関数テンプレートは,その名前の( 非テンプレートの)関数 又は (その他の )同じ名前の
関数テンプレートのいずれとでも多重定義することができる。その名前を( 明示的に 又は 演算子記法を用いて暗黙
に )呼び出すと,各関数テンプレートに対し ,テンプレートの実引数導出(
)及び 明示的なテンプレート実
引数(
)すべてに対する検査が行われ,その関数テンプレートに用いるテンプレート実引数の値を見つけ出し ,
その実引数を与えた呼出しで関数テンプレート特殊化が具現できるかど うかが調べられる。各関数テンプレートに対
し ,実引数導出 及び 検査が成功した場合,その( 導出された 及び/又は 明示的な )
《テンプレート実引数》を用い
て,それぞれ一つの関数テンプレート特殊化が具現され,具現された関数テンプレート特殊化が,多重定義解決で用
いられる候補関数集合に追加される。実引数導出が失敗した関数テンプレートに対しては,そのテンプレートに対す
る候補関数の集合にこうした関数が加えられることはない。候補関数の完全な集合は,この方法で具現された関数テ
ンプレートのすべて 及び 同じ名前をもつ非テンプレートの多重定義関数のすべてを含む。関数テンプレート特殊化
は,これらの
の規定を除いて,多重定義解決に関して,他の関数と同様に扱われる
。
例
Q
23&
R
Q
L
%
&
''
+
%
&
''
*
%
&
''
エラー
3
を生成できない
R
注
関数テンプレート特殊化の仮引数は,テンプレート仮引数型を含まない。実引数の導出では,仮引数が,その呼出しの実引数に厳密に
一致するか,又は 許されている限定された変換によって橋渡し可能という違いだけの関数テンプレートを生成するので,導出された実
引数に許される変換は,限定されている。導出されていない実引数には,すべての変換が許されている。多重定義の合致で,テンプレー
ト特殊化と非テンプレートの関数とが,その違いを除いて等価な候補の場合,テンプレート特殊化よりも非テンプレートの関数に優先権
があると,
で規定していることに注意する必要がある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
上の例に,
&
という非テンプレートの関数を追加した場合,
の
に
から
への標準変換を適用することで,
に対して,呼出し可能な関数が提供可能となり,
番
目の呼出しを解決できる。
《テンプレート実引数》の導出が,関数実引数の変換を生ずる例を示す。
"
Q
'!
(((
!'
R&
#
3
"
Q
'!
(((
!'
R&
"0 &
"0
#0
Q
&
''
&
''
"0
R
《テンプレート実引数》の導出とは関係ない関数実引数の変換の例を挙げる。
! &
''
L
&
''
+
!
Q
&
''
L3
&
''
+3
!
&
''
+3
&
&
''
+3
R
候補関数の集合に特殊化を含めるには,関数テンプレート特殊化の呼出し情報だけが必要となる。したがって,テ
ンプレート特殊化が候補となる呼出しの解決には,関数宣言だけが必要となる。
例
&
''
宣言
Q
Y6Y &
''
!
の呼出し
R
の呼出しは,その呼出し位置でテンプレート
が宣言されているが定義されていない場合にも適格と
なる。そのプログラムは,
!
の特殊化が,暗黙に生成されたものも明示的に生成されたも
のも,どの翻訳単位にも存在しない場合,不適格となる。
#
例外処理
例外処理は,プログラム実行のある位置から,実行が以前に通過した位置に関連付けられた例外ハ
ンド ラに,制御 及び 情報を渡す手段を提供する。ハンド ラは,そのハンド ラの監視ブロック内で実行されるコード
の中で,又は そのハンド ラの監視ブロックから呼び出された関数の中で送出式が起動されることによってだけ起動さ
れる。
監視ブロック
3
複合文
ハンド ラ列
関数監視ブロック
3
コンストラクタ初期化子
関数本体
ハンド ラ列
ハンド ラ列
3
ハンド ラ
ハンド ラ列
ハンド ラ
3
例外宣言
複合文
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
例外宣言
3
型指定子列
宣言子
型指定子列
抽象宣言子
型指定子列
(((
送出式
3
代入式
《監視ブロック》は,
《文》
(
(
)の一つとする。
《送出式》は,
0
3
型とする。
《送出式》を実行するコード は,
:
例外
を送出する
;
。それによって制御を得るコード を
:
ハンド ラ
;
と呼ぶ。
参考
この箇条では,
:
監視ブロック
;
といった場合,
《監視ブロック》 及び 《関数監視ブロック》の二つを意
味する。
文 又は
!<
文を用いて,監視ブロック 又は ハンド ラの内側へ制御を移動してはならない。
例
Q
L&
''
不適格
+&
''
不適格
Q
L&
''
B>
+&
''
不適格
L3
&
R
(((
Q
+3
&
L&
''
不適格
+&
''
B>
R
R
文,
%I
文,
文 又は
文を用いて,制御ブロック 又は ハンド ラの外側へ制御を移動することが
できる。移動が起きた場合,監視ブロックで宣言された変数は,その変数の宣言を直接含む文脈に従って解体される。
例
3
Q
L
L&
Q
+
+&
条件
&
R
(((
Q
'!
ハンド ラ
+
!'
R
R
(((
Q
'!
ハンド ラ
L
!'
R
この例で,条件に変数の宣言がないものとすると,
&
の実行によって,
+
及び
L
がこの順に解体される。
+
の解体中に例外が発生した場合は,ハンド ラ
が実行されることになる。
L
の解体中に例外が発生した場合は,ハ
ンド ラ
が実行されることになる。
《関数監視ブロック》は,
( 存在する場合には )
《コンストラクタ初期化子》 及び 《関数本体》に《ハンド ラ列》を
結び付ける。
《コンストラクタ初期化子》の中の初期化子式の実行中,又は 《関数本体》の実行中に送出された例外
は,
《監視ブロック》の実行中に送出された例外が他のハンド ラに制御を移動するのと同じ方法で,
《関数監視ブロック》
のハンド ラに制御を移動する。
例
&
7
Q
&
&
3
7
&
R&
7337
3
Q
''
コンストラクタ関数の本体
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
R
(((
Q
''
コンストラクタ初期化子 及び コンストラクタ関数本体から
''
送出される例外を処理する
R
#
例外の送出
例外が送出された場合,ハンド ラに制御が移動する。オブジェクトが渡され,そのオブジェクト
の型に従って,どのハンド ラがそれを捕そくできるかが決まる。
例
Y;[Y&
これは,次の
!
型のハンド ラによって捕そくできる。
Q
''
(((
R
!
Q
''
ここで文字列の例外を処理する。
R
そして,
B
Q
''(((
3
B
&
R&
Q
''(((
BZ)Z
*(M/L., &
R
これは,次の型
B
の例外ハンド ラによって捕そくできる。
Q
''(((
L(+ &
''(((
R
B0
Q
''
ここで,型
B
の例外を処理する。
R
例外が送出された場合,一致する型(
#
)をもつ最も近いハンド ラに制御が移動する。ここで,
:
最も近いハン
ド ラ
;
とは,制御のスレッドが最近そこに入りそこからまだ抜けていない,キーワード
に続く《複文》,
《コンス
トラクタ初期化子》 又は 《関数本体》に対するハンド ラとする。
《送出式》は,例外オブジェクトと呼ぶ,一時オブジェクトを初期化する。その型は,次のとおりに決める。
―
の演算対象の静的な型から,最上位の《
0
修飾子》を取り除く。
―
次に,その型が
:
の配列
;
の場合は
:
へのポインタ
;
へ調整し,その型が
:
を返す関数
;
の場合は
:
を
返す関数へのポインタ
;
へ調整する。
参考
《送出式》に対して作られる一時オブジェクトが文字列リテラルの場合,その型は,決して
!
型 又
は
!
型とはならない。すなわち,文字列リテラルに対する,
:
の配列
;
型 又は
:
の配列
;
型から
:
へのポインタ
;
型 又は
:
へのポインタ
;
型への特殊変換(
)は,
《送出式》に対しては適用されない。
その一時オブジェクトは,一致する《ハンド ラ》
(
#
)内で命名される変数を初期化するために使う。
《送出式》の
型は,不完全型,又は 不完全型へのポ インタ 若し くは 参照であってはならない。ただし ,
!
,
!
,
!
及び
!
であってよい。これらの制約 及び
#
で示す型の一致の制約を除
き,
の演算対象は,呼出し時の関数実引数(
#
) 又は
文の演算対象と完全に同じに扱う。
送出される例外の一時的コピーに対するメモリの割付けは,
)
で規定したことを除き,未規定とする。その
一時的コピーは,その例外に対し実行されるハンド ラが存在する限り,存在し続ける。特に,あるハンド ラが
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
という文の実行によって抜け出す場合,そのハンド ラは,同じ例外に対する他のハンド ラに制御を渡すので,その一
時的変数は残っている。例外に対して実行される最後のハンド ラが
&
という文ではない方法で抜け出す場合,
その一時オブジェクトは,解体される。処理系は,その一時オブジェクトのメモリを解放してもよい。その解放の方
法は,未規定とする。解体は,ハンド ラにおける《例外宣言》の中に宣言されたオブジェクトの解体直後に発生する。
一次オブジェクト(
)に対する一連のコンストラクタ 及び デストラクタの実行を除けば ,その一時オブジェ
クトの使用を削除してもプログラムの意味が変わらない場合,ハンド ラにおける例外は,
<
式の実引数で直接に
初期化してもよい。送出されたオブジェクトがクラスオブジェクトであって,その一時的コピーを初期化するために
使うコピーコンストラクタがアクセスできない場合,そのプログラムは不適格とする(アクセスできていれば ,その
一時オブジェクトが削除できたとしても,不適格とする。)
。同様に,そのオブジェクトのデストラクタがアクセスで
きない場合も,そのプログラムは不適格とする(アクセスできていれば ,その一時オブジェクトが削除できたとして
も,不適格とする。)
。
実引数のない《送出式》は,処理中の例外を再送出する。その例外は,既存の一時オブジェクトを使って再活性
化される。すなわち,新し い一時的例外オブジェクトは生成されない。その例外は,もはや捕そく中でなくなり,
の値も再び
となる。
例
例外に対して実行されなければならないものの,その例外を完全には処理できないコード は,次のように
書くことができる。
Q
''
(((
R
(((
Q
''
すべての例外を補足する。
''
( 部分的に )例外に応答する。
&
''
例外を他のハンド ラに渡す。
R
送出された例外とは,最近に捕そくされたが完了していない例外とする。例外は,対応する
節の仮引数に対
して初期化が完了した時,又は 送出のために
(
##
) 又は
(
##
)に入った時に,
捕そくされたとする。例外は,対応する
節を抜け出す時,又は 送出のために入った
を抜け出す
時に,完了したとする。
処理中の例外がない場合に演算対象のない《送出式》を実行すると,
が呼び出される(
##
参照)
。
#
コンスト ラクタ 及び デスト ラクタ
《送出式》からハンド ラに制御が渡るとき,監視ブロックに入ってから
構築されたすべての自動記憶域オブジェクトに対して,デストラクタが呼び出される。その自動記憶域オブジェクト
の解体は,その構築完了順の逆順で行われる。
部分的に構築されているオブジェクト 又は 部分的に解体されているオブジェクトは,そのオブジェクトの完全に構
築されたすべての部分オブジェクト,すなわち,コンストラクタが実行を完了しデストラクタがまだ実行を開始して
いない部分オブジェクトに対して,デストラクタを実行させることになる。自動記憶域配列の要素のコンストラクタ
が例外を送出した場合には,その配列の構築済みの要素だけが解体される。オブジェクト 又は 配列が《
<
式》で
割り付けられている場合,合致する解放関数(
)
,
#
及び
#
参照)が存在するときには,その解放関数
が呼び出されて,そのオブジェクトが占有する記憶域を解放する。
監視ブロックから《送出式》への経路で構築された自動記憶域オブジェクトに対するデストラクタの呼出しの処理
のことを,
:
スタック巻戻し
;
と呼ぶ。
参考
スタック巻戻し中に呼び出されたデストラクタが,例外をもって抜け出した場合,
が呼び出
される(
##
参照)
。したがって,デストラクタは,一般に例外を補足することが望ましく,それをデ
ストラクタの外に伝ぱ( 播)させないほうがよい。
#
例外の処理
《ハンド ラ》の《例外宣言》では,その《ハンド ラ》に入ることが可能になる例外の型を記述す
る。
《例外宣言》は,不完全な型,又は 不完全な型へのポインタ 若しくは 参照を表してはならない。ただし,
!
,
!
,
!
及び
!
は表してもよい。
《例外宣言》の中では,型を定義し
てはならない。
:
の配列
;
型 又は
:
を返す関数
;
型のハンド ラの型は,その型が
:
の配列
;
の場合は
:
へのポインタ
;
型に
調整され,その型が
:
を返す関数
;
の場合は
:
を返す関数へのポインタ
;
型に調整される。
《ハンド ラ》は,次のいずれかの場合に,型
.
の例外オブジェクトに合致する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
―
《ハンド ラ》の型が,
又は
0
であって,
.
及び
が,
( 最上位の《
0
修飾子》を無視して )同
じ型の場合。
―
《ハンド ラ》の型が,
又は
0
であって,
が,
.
のあいまいさのない公開基底クラスの場合。
―
《ハンド ラ》の型が,
であって,
.
が,次のいずれか 又は 両方によって《ハンド ラ》の型に
変換できるポインタ型の場合。
非公開 若しくは 限定公開のクラスへのポインタ,又は あいまいなクラスへのポインタへの変
換を含まない標準的なポインタ変換(
)
。
修飾変換。
参考
ゼロをもたらす整数型の汎整数定数式である《送出式》は,ポインタ型のハンド ラとは合致しない。す
なわち,空ポインタ定数変換(
及び
参照)は適用されない。
監視ブロックに対するハンド ラは,出現順に試行される。そのために,決して実行されないハンド ラを記述するこ
とも可能になる。例えば ,対応する基底クラスに対するハンド ラの後ろに置いた派生クラスに対するハンド ラは,実
行されることがない。
例
@
Q
'!
(((
!'
&
R&
B3
@
Q
'!
(((
!'
R&
G3
@
Q
'!
(((
!'
R&
K3
@
Q
'!
(((
!'
R&
Q
Q
&
R
B
Q
''
(((
R
@
Q
''
(((
R
R
この例で,
B
ハンド ラは,型
B
の例外を捕そくし,
@
ハンド ラは,型
@
の
例外,並びに 型
G
及び 型
K
の例外を含む
@
から派生した公開されたすべて
の型の例外を捕そくする。
ハンド ラの《例外宣言》に書いた
(((
は,関数仮引数宣言に書いた
(((
と同様に機能する。すなわち,あらゆる
例外に対して合致する指定となる。
(((
ハンド ラは,設けるならば,監視ブロックに対する最終のハンド ラでなけれ
ばならない。
監視ブロックに対するハンド ラの中に合致するものが存在しない場合,合致するハンド ラの探索が,動的に取り囲
む監視ブロックにおいて継続される。
例外は,ハンド ラへの入口に達した時点で処理されるとみなす。
参考
スタックは,その時点で巻き戻されてしまう。
プログラム中に合致するハンド ラが見つからない場合,関数
が呼び出される。
を呼び
出す前にスタックを巻き戻すかど うかは,処理系定義とする(
##
参照)
。
オブジェクトのコンストラクタ 又は デストラクタの《関数監視ブロック》に対するハンド ラの中で,そのオブジェ
クトの非静的メンバ 又は 基底クラスを参照した場合の動作は,未定義とする。
オブジェクトの,完全に構築された基底クラス 及び メンバは,そのオブジェクトのコンストラクタ 又は デストラ
クタの《関数監視ブロック》に対するハンド ラに入る前に,解体されなければならない。
関数 又は コンストラクタの仮引数の有効範囲 及び 生存期間は,
《関数監視ブロック》のハンド ラにまで拡張される。
静的記憶域期間をもつオブジェクトのデストラクタの中,又は 名前空間有効範囲のオブジェクトのコンストラクタ
の中で送出された例外は,
の《関数監視ブロック》では捕そくされない。
《関数監視ブロック》のハンド ラが,コンストラクタ 又は デストラクタの本体への飛越しを含む場合,そのプロ
グラムは不適格とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
コンストラクタの《関数監視ブロック》のハンド ラに
文がある場合,そのプログラムは不適格とする。
コンストラクタ 又は デストラクタの《関数監視ブロック》のハンド ラの最後に制御が到達した場合,処理されて
いる例外は,再送出される。それ以外の《関数監視ブロック》に対するハンド ラの場合,そのハンド ラの最後に制御
が達したとき,関数は返却される(
((
)
。
《関数監視ブロック》の最後で抜け出るのは,値なしの
文と同等
とする。これが値を返す関数でど うなるかは,動作未定義とする(
((
)
。
《例外宣言》がクラス型を指定している場合,コピーコンストラクタを使って,
《例外宣言》で宣言されたオブジェ
クトを初期化するか,
《例外宣言》が名前を指定していないとき,そのクラス型の一時オブジェクトを初期化するかす
る。そのオブジェクトは,抽象クラス型であってはならない。そのオブジェクトは,ハンド ラが抜け出るときであっ
て,そのハンド ラ内で初期化されたあらゆる自動記憶域オブジェクトが解体された後に,解体される。コピーコンス
トラクタ 及び デストラクタは,ハンド ラの文脈でアクセス可能でなければならない。コピーコンストラクタ 及び デ
ストラクタが暗黙的宣言される場合(
),ハンド ラにおけるこのような使い方によって,それらの関数が暗黙的
に定義される。そうでない場合には,プログラムでそれらの関数の定義をしなければならない。
一時オブジェクトの使用に関連したコンストラクタ 及び デストラクタの実行以外では,プログラムの意味を変え
ることなくその一時オブジェクトを使わないようにできる場合,その省略可能な名前は,そのハンド ラを実行させる
《送出式》で指定された一時オブジェクトに直接に結合することができる。そのオブジェクトに関連するコピーコン
ストラクタ 及び デストラクタは,一時オブジェクトを削除した場合であっても,アクセス可能でなければならない。
ハンド ラが定数ではないオブジェクトを宣言した場合,そのオブジェクトへのあらゆる変更は,
《送出式》の実行に
よって初期化された一時オブジェクトに影響しない。ハンド ラが定数ではないオブジェクトへの参照を宣言する場合,
参照されるオブジェクトへのあらゆる変更は,
《送出式》の実行によって初期化された一時オブジェクトへの変更とな
り,そのオブジェクトが再送出される場合には影響を生じる。
#
例外指定
関数宣言では,その関数が直接に 又は 間接に送出するかもしれない例外を,その関数の宣言子の
接尾語としての例外指定を使って,列挙する。
例外指定
3
型識別子並び
型識別子並び
3
型識別子
型識別子並び
型識別子
《例外指定》は,関数宣言,関数定義,ポインタ宣言,ポインタ定義,又は メンバへのポインタ 若しくは 参照の宣
言・定義における関数宣言子に関してだけ現れなければならない。
《例外指定》は,型定義
1
3
宣言に現れては
ならない。
例
&
''
B>
!
&
''
B>
&
''
B>
!
&
''
不適格
《例外指定》の中に表された型は,不完全型 又は 不完全型へのポインタ 若しくは 参照であってはならない。ただし,
!
,
!
,
!
又は
!
であってよい。
関数のいずれかの宣言に《例外指定》がある場合,その関数のすべての宣言は,定義 及び 明示的特殊化を含めて,
《型識別子》の同じ集合をともなう《例外指定》をもたなければならない。関数へのポインタ,関数の参照 又は メン
バ関数へのポインタのいずれかの宣言に《例外指定》がある場合,その宣言のすべての出現は,
《型識別子》の同じ集
合をともなう《例外指定》をもたなければならない。明示的具現化の指令の中に《例外指定》を指定してもよいが ,
それは必す( 須)とはしない。明示的具現化の指令の中に《例外指定》を指定した場合は,その《例外指定》は,そ
の関数の他の宣言と同じ型識別子の集合をもたなければならない。診断は,一つの翻訳単位内で型識別子の集合が異
なる場合にだけ要求される。
仮想関数が《例外指定》をもつ場合,派生クラスでその仮想関数を上書きする関数の( 定義を含めた )すべての宣
言は,その基底クラスの仮想関数の《例外指定》によって許された例外だけを許さなければならない。
例
"
&
&
R&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#3
"
Q
&
''
不適格
&
''
B>
R&
宣言
#33
は,
"33
が
及び
だけを許すのにもかかわらず,すべての例外を許す記述となっ
ているので,不適格となる。
同様の制限が,関数へのポインタ,メンバ関数へのポインタ 及び 関数への参照に対する代入 及び 初期化に適用され
る。すなわち,対象となる実体は,少なくとも,代入 又は 初期化の元の値が許す例外を許さなければならない。
例
6
Q
'!
(((
!'
R&
!L
&
''
例外指定なし 。
!+
6 &
Q
L
%
+&
''
B>3
L
のほうが,制約が弱い。
+
%
L&
''
エラー
3
+
のほうが,制約が強い。
R
このような代入 又は 初期化においては,返却値の型 及び 仮引数の型に関する《例外指定》が,完全に一致しなけ
ればならない。他の代入 又は 初期化では,
《例外指定》は完全に一致しなければならない。
型を《例外指定》の中で定義してはならない。
《例外指定》には,同一の型を
回以上指定してもよいし,継承関係にあるクラスを指定してもよいが,それは冗
長になる。
《例外指定》には,クラス
33
(
(
)を指定することもできる。
関数は,その《例外指定》が型
を含み,型
のハンド ラが型
.
の例外に対して合致するものとなる(
#
)場
合に,型
.
の例外を許容するという。
例外が送出され,ハンド ラの検索(
#
)が《例外指定》をもつ関数の最外側ブロックに到達した場合,その《例
外指定》がその例外を許していないときは,関数
を呼び出す(
##
参照)
。
例
5
Q
R&
J
Q
R&
K3
5
Q
R&
I
Q
R&
5
J
Q
%
.&
5 &
''
B>
K &
''
これも
B>
I &
''
を呼び出す。
R
関数
は,それを呼び出すに到った( 関数の )
《例外指定》を満たす例外を送出してもよい。その場
合,他のハンド ラの検索が,この《例外指定》をもつ関数の呼出し点で継続される(
##
)が,
を呼
び出してもよい。
処理系は,ある式を実行した場合に,その式を含む関数が許さない例外を送出する,又は 送出するかもしれないと
いうだけの理由から,その式を拒否してはならない。
例
5
J &
5
Q
&
''
B>
R
ここで,
を呼び出した場合,
が許さない例外
J
を
が送出するかもしれないが,
の呼出しは,適
格とする。
《例外指定》をもたない関数は,すべての例外を許す。空の《例外指定》
をもつ関数は,あらゆる例外を
許さない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
《例外指定》は,関数の型の一部とは考えない。
暗黙的に宣言される特殊メンバ関数(
)は,
《例外指定》をもたなければならない。
を,暗黙的に宣言される,
省略時コンストラクタ,コピーコンストラクタ,デストラクタ 又は コピー代入演算子とする場合,その暗黙的な《例
外指定》は,
の暗黙的定義によって直接に呼び出される関数の《例外指定》によって
が許される場合に限り,型
識別子
を指定する。
が直接的に呼び出すいかなる関数もすべての例外を許す場合には,
は,すべての例外を許
さなければならず,
が直接的に呼び出すすべての関数がいかなる例外も許さない場合には,
は,いかなる例外も
許してはならない。
例
6
Q
6 &
6
60
&
X6
5 &
R&
"
Q
"
&
"
"0
&
X"
J &
R&
#3
6
"
Q
''
#33# &
の暗黙的宣言
''
#33#
#0
&
の暗黙的宣言
''
#33X#
5
J &
の暗黙的宣言
R&
さらに,
633X6
又は
"33X"
が仮想の場合,
#33X#
は,
633X6
ほどは制約が強くないが ,基底クラ
スからの仮想関数を上書きする関数は,少なくとも,基底クラスの場合と同じほど 制約的な《例外指定》
をもたなければならないので,このプログラムは不適格となる。
##
特殊関数
例外処理機構は,二つの関数,
及び
を用いて,例外処理機構自体に関
係するエラーに対処する(
(
)
。
##
関数
次の状況では,例外処理は,より重大なエラー処理手法に移るために放棄されなければ
ならない。
―
送出される式の評価が完了した後だがその例外が捕そくされる前(
#
)に,例外処理機構が利用者関数
を呼び出し ,その利用者関数がまだ捕そくされていない例外をもって抜け出る場合。
―
送出された例外に対するハンド ラを,例外処理機構が見つけられない場合(
#
)
。
―
スタック巻戻し(
#
)中のオブジェクトの解体が,例外をもって抜け出る場合。
―
静的記憶域期間の非局所オブジェクトの構築 又は 解体が,例外を使って抜け出る場合(
(
)
。
―
で登録された関数の実行が,例外を使って抜け出る場合(
)
。
―
演算対象なしの《送出式》が,例外を再送出しようとしたが,どの例外も処理中ではない場合(
#
)
。
―
以前に違反のあった《例外指定》によって許されていない例外を,
が送出した場合であって,
33
がその《例外指定》に含まれない場合(
##
)
。
―
処理系の省略時ハンド ラ
が呼び出された場合(
(
)
。
これらの場合,次の関数が呼び出される(
(
参照)
。
&
合致するハンド ラが見つからない状況では,
を呼び出す前にスタックを巻き戻すかど うかは,処理系定
義とする。その他のすべての状況では,
を呼び出す前にスタックを巻き戻してはならない。処理系は,
巻戻しの処理がいずれ
の呼出しを引き起こすという早まった決定に基づいて,スタック巻戻しを完了し
てはならない。
##
関数
《例外指定》付きの関数が,
《例外指定》に列挙されていない例外を送出する場合,そ
の関数のスタック巻戻しが完了した直後に,次の関数が呼び出される(
(
)
。
&
関数が戻ることはないが,例外の送出( 又は 再送出)はできる。その関数が以前に違反した《例外
指定》によって許される新たな例外を送出する場合,違反した《例外指定》をもつ関数の呼出し点で他のハンド ラの
注
例えば ,送出されているオブジェクトがコピーコンストラクタをもったクラスの場合,送出中にそのコピーコンストラクタが例外を
もって抜け出る場合には,
が呼び出される。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
探索が続けられる。その関数が《例外指定》が許さない例外を送出 又は 再送出する場合,次のことが起こる。すな
わち,
《例外指定》がクラス
33
(
(
)を含まない場合には,
関数が呼び出され
るが,含む場合には,送出された例外は,型
33
の処理系定義のオブジェクトに置き換えられ,そ
の違反した《例外指定》をもつ関数の呼出し点で他のハンド ラの探索が続けられる。
こうして,列挙された例外だけが送出されることが《例外指定》によって保証される。
《例外指定》が型
33
を含む場合には,列挙されていないあらゆる例外は,
関数内
で,
33
に置き換えられてよい。
##
関数
次の関数は,送出するオブジェクトの評価を完了した後で,合致するハンド
ラの中の《例外宣言》の初期化が完了するまでの間,
を返す(
(
)
。
P
これには,スタック巻戻しが含まれる。例外が再送出される場合(
#
)には,
は,再送出
の時点から,その再送出された例外が捕そくされるまでの間,
を返す。
#(
例外 及び アクセス
節の中の《例外宣言》がクラス型をもち,
節が出現する関数がそのクラス
のデストラクタへのアクセスをもたない場合,そのプログラムは不適格とする。
オブジェクトが《送出式》の出現する関数の文脈の中でコピー 及び 解体が可能な場合には,そのオブジェクトを
送出することができる。
(
前処理指令
前処理指令は,前処理字句の列で構成する。その列の先頭の字句は,次の二つの条件のいずれか
を満たす前処理字句
とする。
―
ソースファイル中の最初の文字である( 改行文字を含まない空白類の後であってもよい。)
。
―
少なくとも一つの改行文字を含む空白類の後に続く。
その列の最後の字句は,その列の最初の字句に続く最初の改行文字とする
。
前処理ファイル
3
グループ
グループ
3
グループ 構成要素
グループ
グループ構成要素
グループ 構成要素
3
前処理字句列
改行
節
制御行
節
3
グループ
グループ 列
グループ
行
グループ
3
定数式
改行
グループ
識別子
改行
グループ
識別子
改行
グループ
グループ列
グループ
グループ 列
グループ
グループ
3
定数式
改行
グループ
グループ
3
改行
グループ
行
3
改行
制御行
3
注
このため,一般に前処理指令を
行
と呼ぶ。
行
には,これ以外の構文的意味はない。前処理中の特定の場合(例えば,
の
文字列リテラル作成演算子
9
を参照)を除いて,すべての空白類は等価であるからである。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
前処理字句列
改行
識別子
置換内容列
改行
識別子
左括弧
識別子並び
置換内容列
改行
識別子
改行
前処理字句列
改行
前処理字句列
改行
前処理字句列
改行
改行
左括弧
3
直前に空白類のない左括弧文字
置換内容列
3
前処理字句列
前処理字句列
3
前処理字句
前処理字句列
前処理字句
改行
3
改行文字
前処理指令中( 前処理字句
の直後から,その終端にある改行文字の直前まで )の前処理字句の間に現れてよい空
白類文字は,空白 及び 水平タブだけとする( 注釈 又は その他の空白類文字を翻訳段階
で置換した空白も含む。)
。
処理系は,ソースファイルの一部分を条件によって処理したり読み飛ばしたり,他のソースファイルを読み込んだ
り,マクロを置き換えたりすることができる。これらの処理は,概念的にはその翻訳単位の翻訳の前に行われるので,
前処理と呼ぶ。
前処理指令中の前処理字句は,特に規定する場合を除いてマクロ展開の対象とはならない。
(
条件付き取込み
条件付き取込みを制御する式は,汎整数定数式でなければならない。ただし,キャストを含ん
ではならず,識別子(キーワード と字句的に同じものを含む。)は,ここに規定する意味規則に従って解釈する
。
更に,次の形式の単項演算子式を含んでいてもよい。
識別子
又は
識別子
これらの単項演算子の評価結果は,識別子がマクロ名として定義されている場合( すなわち,あらかじめ定義されて
いるか,又は 前処理指令
の対象となったことがあり,しかもその後に同じ識別子に対する前処理指令
がない場合)
と評価し ,そうでない場合
と評価する。
すべてのマクロ置換の後に残った前処理字句は,それぞれが字句としての形式になっていなければならない(
(
参照)
。
次の形式の前処理指令は,その定数式(これを制御定数式と呼ぶ。)を評価した結果が
以外かど うかを検査する。
定数式
改行
グループ
定数式
改行
グループ
評価に先立って,制御定数式となる前処理字句の並びの中のマクロ呼出しを,普通のテキストと同様に(
単項演算子の対象となっているマクロ名を除いて )置き換える。この置換処理によって字句
が生成される場
合,又は マクロ置換前の
単項演算子の使用法が,規定した二つの形式のど ちらにも一致しない場合,その
動作は未定義とする。マクロ展開 及び
単項演算子によるすべての置換の実行後,残っているすべての識別
子,及び
と
を除くキーワード
を前処理数
.
で置き換えてから,各前処理字句を字句に変換する。こ
の結果得られた一連の字句を,制御定数式として
#*
の規定に従って評価する。この評価では,少なくとも
に
規定した範囲をもつ算術型を使い,
及び
が,それぞれ
及び
の表現をもつ
として扱う。この処理の中で,文字リテラルの解釈が生じることもある。その解釈に際しては,逆斜線表記を実行文
字集合の要素へ変換する。それらの文字リテラルの数値が,同じ文字リテラルを(
又は
指令の中以外の )
注
制御定数式は,翻訳段階
-
の中で評価するので,すべての識別子は,マクロ名であるか否かのいずれかとなる。すなわち,キーワー
ド,列挙定数などはまだ存在しない。
注
代替字句
は,そのつづりがすべて文字 及び 下線だけであったとしても,識別子ではない。したがって,代替字句は,置換の対
象とはならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
式の中に書いたときに得られる値に一致するか否かは,処理系定義とする
。更に,単一文字からなる文字リテ
ラルが負の値をもつことがあるか否かは,処理系定義とする。型
をもつ各部分式には,処理の前に汎整数昇格
を施す。
次の形式の前処理指令は,識別子がその時点でマクロ名として定義されているか否かを検査する。
識別子
改行
グループ
識別子
改行
グループ
これらの前処理指令は,それぞれ
識別子 及び
[
識別子と等価とする。
各指令の条件は,順に検査される。その条件が偽(ゼロ)と評価される場合,それが制御するグループを読み飛ば
す。このとき,そのグループ内の前処理指令は,その指令の種類を決める名前だけを見て,
節の入れ子のレベルを
追跡する処理を行う。前処理指令のそれ以降の前処理字句 及び グループ内の他の前処理字句は,すべて無視する。制
御条件が真(ゼロ以外)と評価された最初のグループだけを処理する。どの条件も真と評価されない場合,
指
令があるときは,
で制御されるグループを処理し,
指令がないときは,
までのすべてのグループ
を読み飛ばす
。
(
ソースファイルの取込み
指令は,処理系で処理できるヘッダ 又は ソースファイルを識別しなけれ
ばならない。
次の形式の前処理指令は,処理系定義の場所を順に探索し ,区切り記号
と
との間で指定した文字列で一意に
決まるヘッダを見つけ,そのヘッダの内容全体でこの指令を置き換える。
文字列
改行
どのようにして探索の場所を指定するか,またどのようにしてヘッダを識別するかは,処理系定義とする。
次の形式の前処理指令は,二つの区切り記号
Y
の間で指定されたソースファイル全体の内容で,この指令を置き換
える。
Y
文字列
Y
改行
指定されたソースファイルの探索手順は,処理系定義とする。この探索を提供していない場合 又は 探索が失敗した
場合,同一の文字列(その中に文字
が含まれていてもよい。)を含む次の形の指令に読み替えて,再処理する。
文字列
改行
次の( 上の二つの形式のど ちらとも一致しない)形式の前処理指令も許す。
前処理字句列
改行
この指令中の,
の後ろにある前処理字句列は,通常のテキストと同様に処理する(その時点でマクロ名とし
て定義されている各識別子は,その識別子の前処理字句に置き換える。)
。すべての置き換えを行った後の指令が,上
の二つの形式のど ちらとも一致しない場合,その動作は未定義とする
。区切り記号
と
,又は 二つの
Y
で囲
まれた前処理字句の列を,一つのヘッダ名の前処理字句として解釈する方法は,処理系定義とする。
区切り記号で囲まれた列と外部ソースファイル名の間の対応付けは,処理系定義とする。処理系は,一個以上の非
数字
の列の後ろにピリオド
(
が来て
個の非数字が続く形式に対して,一意の対応付けを提供しなければな
らない。処理系は,アルファベットの大文字小文字の区別を無視してもよい。
前処理指令は,入れ子になっていてもよい。すなわち,処理系定義の入れ子の制限内で,他のファイル
の
前処理指令によって取り込まれたソースファイルの中に現れてもよい。
例
前処理指令として,最も一般的な用法を次に示す。
(
Y(Y
例
次の例は,マクロ置換される
指令を示している。
H8EF<BA
%%
L
<A79<?8
YL(Y
H8EF<BA
%%
+
注
すなわち,次の
9%
指令 及び
%
文の中の定数式がこの二つの文脈の中で同じ値として評価されるという保証はない。
9%
:-:
6
::
;;
3<
%
:-:
6
::
;;
3<
注
構文規則が示すとおり,
9
指令 又は
9&%
指令の後では改行文字の前に前処理字句を書いてはならない。しかし ,注釈は,前
処理指令の中を含めて,どこに書いてもよい。
注
隣接した文字列リテラルが,連結して一つの文字列リテラルになることはない(
翻訳段階参照)
。したがって,展開の結果二つの
文字列リテラルが現れると正しくない指令となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
<A79<?8
Y+(Y
'!
以下同じ
!'
<A79<?8
YA(Y
<A79<?8
(
マクロ置換
二つの置換内容列は,その前処理字句の個数,順序,つづり,及び 空白類による区切り方が同じ
場合,そして,その場合に限り,同一の並びとみなす。ただし ,空白類による区切りは,どれも同じものとみなす。
左括弧を用いないマクロ(オブジェクト形式マクロ)としてその時点で定義されている識別子は,次の二つの条件
をともに満たす場合に限り,他の
前処理指令によって再定義してもよい。そうでない場合,プログラムは不
適格とする。
―
番目の定義がオブジェクト形式マクロの定義である。
―
それら二つの置換内容列が同一である。
左括弧を用いるマクロ( 関数形式マクロ)としてその時点で定義されている識別子は,次の二つの条件をともに満
たす場合に限り,他の
前処理指令によって再定義してもよい。そうでない場合,プログラムは不適格とする。
―
番目の定義が,最初の定義と同じ個数 及び 同じつづりの仮引数をもつ関数形式マクロの定義である。
―
それら二つの置換内容列が同一である。
関数形式マクロの呼出しにおける実引数の個数は,マクロ定義内の仮引数の個数と一致していなければならず,呼
出しの終了を示す前処理字句
: ;
がなければならない。
関数形式マクロにおける仮引数識別子は,その有効範囲内で一意に宣言していなければならない。
の直後に来ている識別子を,マクロ名という。マクロ名に対する名前空間が一つ存在する。いずれのマク
ロ形式においても,置換内容列の前処理字句列の前 又は 後にある空白類文字は,置換内容列の一部とみなさない。
字句的に前処理指令の始まりとして許される位置に,前処理字句
に続いて識別子が現れた場合,その識別子は,
マクロ置換の対象とはならない。
次の形式の前処理指令は,オブジェクト形式マクロを定義する。
識別子
置換内容列
改行
以後,そのマクロ名
が現れた場合は,この指令の残りを構成する置換内容列の前処理字句列でそのマクロ名を
置き換える
。その上で,この置換内容列を再走査して,その中に更にマクロ名があるかど うかを調べる。
次の形式の前処理指令は,構文的に関数呼出しと類似した,仮引数付きの関数形式マクロを定義する。
識別子
左括弧
識別子並び
置換内容列
改行
仮引数は,省略可能な識別子並びで指定し,その有効範囲は,識別子並びの中でのその宣言から,
前処理指
令の終わりの改行文字までとする。以後,この関数形式マクロ名の直後に
:;
が現れたときは,そのマクロ名からそ
の
:;
に対応する
: ;
まで( マクロ呼出し )をこの定義の中の置換内容列で置き換える。この
:;
と
: ;
の対応を調
べる際には,その間に左右対となる前処理字句の括弧があっても,それらを無視する。関数形式マクロの呼出しを構
成する前処理字句列の中では,改行は通常の空白類文字とみなす。
最も外側の括弧で囲まれた前処理字句列は,関数形式マクロの実引数の並びを構成する。並びの中の個々の実引数
は,コンマ前処理字句で区切る。ただし ,内側の対をなす括弧の中のコンマ前処理字句は,実引数を区切らない。実
引数が,
実引数代入の前に
前処理字句を含まない場合は,その動作は未定義とする。実引数の並びの中に,ほかの
場合であれば前処理指令として働く前処理字句列がある場合,その動作は未定義とする。
(
実引数代入
関数形式マクロ呼出しの実引数を識別した後,実引数代入を行う。置換内容列の中に現れた仮
引数に,対応する実引数を代入する。この代入に先だって,実引数の中のすべてのマクロを展開する。ただし ,置換
内容列の中の次の仮引数は除く。
―
前処理字句
又は
が前にある仮引数
―
前処理字句
が後に続く仮引数
実引数代入の前に,各実引数の前処理字句の列を,それらが翻訳単位のすべてであるかのように扱って,完全にマク
ロ置換を行う。このとき,他の前処理字句はないものとみなす。
注
マクロ置換の時点までには,文字リテラル 及び 文字列リテラルは,それぞれ
個の前処理字句になっていて,識別子含みうる文字の
列ではなくなっている(
の翻訳段階参照。)から,これらの中を走査してマクロ名や仮引数を探すことはない。
注
代替字句
./
は,そのつづりが文字 及び 下線だけでできていても,識別子ではない。したがって,代替字句と同じ名前のマクロを
定義することはできない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
(
演算子
関数形式マクロの置換内容列の中にある前処理字句
の直後には,置換内容列の中の次の前処理
字句として,仮引数が続かなければならない。
置換内容列の中で,仮引数の直前に 前処理字句
が置かれている場合,その前処理字句
及び 仮引数を,対応す
る実引数の前処理字句列のつづりを含んだ一つのナロー文字列リテラル前処理字句で置き換える。実引数の前処理字
句の間にある各空白類は,ナロー文字列リテラルの中で
個の空白文字になる。実引数の最初の前処理字句の前と最
後の前処理字句の後ろの空白類は,削除する。これらを除けば,実引数の各前処理字句の元のつづりが,そのままナ
ロー文字列リテラルの中に保持される。ただし ,文字列リテラル 及び 文字定数のつづりを生成するための特別の処
理,すなわち,文字定数 又は 文字列リテラルの( 区切りのための
Y
文字も含めた )
Y
文字 及び
4
文字の前に
4
文
字をそれぞれ挿入する処理が行われる。置換の結果が正しいナロー文字列リテラルでない場合,その動作は未定義と
する。
演算子 及び
演算子の評価順序は,未規定とする。
(
演算子
前処理字句
は,マクロ定義のど ちらの形式においても置換内容列の始まり 又は 終わりに現
れてはならない。
置換内容列中で,仮引数の直前 又は 直後に 前処理字句
が置かれている場合,その仮引数を対応する実引数の
前処理字句列で置き換える。
オブジェクト形式マクロ 及び 関数形式マクロのいずれの呼出しにおいても,その置換内容列を再検査して,更に
置き換えるべきマクロ名があるかど うかを調べる前に,置換内容列中の各前処理字句
( 実引数からもたらされた前
処理字句
は除く。)の出現を削除し,その直前にある前処理字句とその直後の前処理字句とを連結する。その結果
が正しい前処理字句にならない場合,その動作は未定義とする。その結果の字句は,その後のマクロ置換の対象とな
る。演算子
の評価順序は,未規定とする。
(
再走査 及び 再置換
置換内容列の中のすべての仮引数の置換後,その結果の前処理字句列 及び それに続
くソースファイル上のすべての前処理字句を再走査して,更に置き換えるべきマクロ名があるかど うかを調べる。
この再走査中に,置換内容列の中(ソースファイルの残りの前処理字句は含まない。)に現在置換中のマクロの名
前を見つけた場合,置換は行わない。更に,入れ子になった置換の中で現在置換中のマクロの名前を見つけても,置
換は行なわない。そうした置換対象外となったマクロ名の前処理字句は,たとえ他の場合であれば置換が起きる文脈
上で( 再)検出されても,もはや再置換の対象とはならない。
完全にマクロ置換した前処理字句列は,その結果が前処理指令の形をしていたとしても,前処理指令として処理す
ることはない。
(#
マクロ定義の有効範囲
マクロ定義は,
(ブロック構造とは独立に )対応する
指令を検出するまで,
又は(それがなければ )翻訳単位の最後まで有効とする。
次の形式の前処理指令は,指定された識別子のマクロ名としての定義を無効にする。
識別子
改行
指定された識別子がその時点でマクロ名として定義されていない場合,この指令を無視する。
参考
この機能の最も単純な使い方は,例えば次のような
:
定数名
;
の定義である。
6"F<K8
L..
S6"F<K8T&
次の例では,実引数の中で最大のものを値とする関数形式マクロを定義している。このマクロは,次の
利点をもつ。
―
実引数のいかなる適合する型に対しても動作する。
―
関数呼出しのオーバヘッド のないインラインコード を生成する。
このマクロは,次の欠点をもつ。
―
実引数の一方を( 副作用を含め )
回評価する。
―
何度も呼び出される場合に,関数に比べてコード を多く生成する。
更に,アドレスをもたないので,アドレスを得ることもできない。
2
3
括弧を用いて,実引数と結果の式が適切に結合されることを保証している。
再定義 及び 再検査の規則の例を,次に示す。
*
!
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
+
$
$S.T
X
. L
)L
)
$
U
.
)
L &
)
*
M
V
1
/
0
W &
この例の結果は,次のようになる。
+
!
)L
)
+
!
+
!
$S.T
U
+
!
.
)
L &
+
!
+
)
*
M
V
. L
1
+
!
X/
0
+
!
. L W. L &
ナロー文字列リテラルの生成 及び 字句の連結の規則の例を,次に示す。
YY
Y%
U
Y
Y%
UY
4
<A79<?8
'!
前の
の例を参照
!'
;<:;?BI
YY
?BI
?BI
Y
Y
L
+ &
Y
4
.Y
YY
Z4MZ
'!
この注釈はなくなる
!'
%%
.
3
]4
&
<A79<?8+ (
;<:;
?BI &
;<:;
?BI
この例は,次の結果になる。
YY
YLY
Y%
U
Y
Y+Y
Y%
UY
L
+ &
Y4
Y
4
4.
4Y
4Y4Y
Z44MZ
%%
.YY3
]4Y
&
Y+(Y
マクロ置換後
処理となる
YY&
YY
Y
Y
更に,ナロー文字列リテラルの連結を行い,最終的には,次の結果になる。
YL%
U
+%
UY
L
+ &
Y4
Y
4
4.
4Y
4Y4Y
Z44MZ
%%
.3
]4Y
&
Y+(Y
YY&
Y
Y
マクロ定義における
字句 及び
字句の前後の空白は,あってもなくてもよい。
最後に,再定義の規則を次に示す。次の再定義は正しい。
B"=P?<>8
LVL
B"=P?<>8
'!
空白類
!'
LVL
'!
その他
!'
9AP?<>8
9AP?<>8
'!
空白類に注意
!'
4
'!
この行にはそれ以外のものが入る
!'
しかし ,次の再定義は,不適格である。
B"=P?<>8
.
'!
字句列が異なる
!'
B"=P?<>8
L
V
L
'!
空白類が異なる
!'
9AP?<>8
'!
仮引数使用方法が異なる
!'
9AP?<>8
'!
仮引数のつづりが異なる
!'
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
(
行制御
指令の文字列リテラルは(それが存在する場合),ナロー文字列リテラルでなければならない。
現在のソース行の行番号は,ソースファイルからの翻訳段階
の処理において,現在の字句までに読み込んだ
改行文字の個数より
L
だけ大きい。
次の形式の前処理指令は,処理系に対し ,この指令以降のソース行の列が数字列(
L.
進整数として解釈する。)で
指定された行番号で始まるとして動作することを指す。
数字列
改行
数字列が
.
,又は
*+,-,
より大きい場合,その動作は未定義とする。
次の形式の前処理指令は,行番号を上と同様に設定し ,ソースファイルを示す名前をナロー文字列リテラルの内容
に変更する。
数字列
Y
文字列
Y
改行
次の形式( 先の二つのど ちらとも一致しない。)の前処理指令も許す。
前処理字句列
改行
この指令の
の後にある前処理字句列は,通常のテキストにある場合と同様に処理する( マクロ名として定義され
ている各識別子は,その置換内容列の前処理字句の列によって置き換える。)
。すべての置換の結果の指令が先の二つ
の形式のど ちらとも一致しない場合,その動作は未定義とする。そうでない場合,結果は一致した形式の規定に従っ
て処理される。
(#
エラー指令
次の形式の前処理指令は,処理系に対し,指定された前処理字句の列を含む診断メッセージを出
力し ,プログラムを不適格と宣告することを指示する。
前処理字句列
改行
((
プラグマ指令
次の形式の前処理指令は,処理系に対し ,処理系定義の方法で動作することを指示する。
前処理字句列
改行
処理系が認識できないプラグマ指令は,無視する。
()
空指令
次の形式の前処理指令は,何の効果もない。
改行
(
あらかじめ定義されたマクロ名
次のマクロ名は,処理系によって定義されていなければならない。
?<A8
現在のソース行の行番号(
進定数)
9<?8
ソースファイルを示す名前(ナロー文字列リテラル )
#68
ソースファイルの翻訳の日付。
(
:@
;
の形式をもつナロー文字列リテラル。ここで,月
の名前
@
は,
関数で生成されるものと同じとする。
の値が
L.
より小さいときは,その最初
の文字は空白とする。)
。翻訳の日付が得られない場合,処理系定義の正しい日付が供給される。
<@8
ソースファイルの翻訳の時刻(
関数の生成する時刻と同じ
:33;
形式のナロー文字
列リテラル )
。翻訳の時刻が得られない場合,処理系定義の正しい時刻が供給される。
F#7
F#7
があらかじめ定義されているかど うか,及び 定義されている場合の値は,処理系定義と
する。
という名前は,
7))
の翻訳単位を翻訳する場合,
LOO,LL?
という値に定義されて
いる
。
あらかじめ定義されたマクロの値は,
(
?<A8
及び
9<?8
を除いて)翻訳単位を通して定数のままとする。
この箇条のあらかじめ定義されたマクロの名前 及び 識別子
が,
又は
前処理指令の対象
になった場合,その動作は未定義とする。
)
ライブラリ
ここでは,標準
"
#
#
ライブラリの内容,適格な
"##
プログラムがライブラリを用いる方法 及び
規格合致処理系がライブラリの各種実体を提供する方法を規定する。
標準
"##
ライブラリは,拡張可能なフレームワークを提供し ,次に示す機能のための部品群をもつ。
―
言語常備
―
診断機能
―
一般ユーティリティ
―
文字列
注
この規格の将来の版では,このマクロの値をより大きい値にしようと意図している。準拠していないコンパイラでは,最大でも
/
桁ま
での
!
進値としなければならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
―
現地化
―
コンテナ
―
反復子
―
アルゴ リズム
―
数値処理
―
入出力
言語常備部品群は,
"##
言語の一部の機能,例えば記憶域割付け(
#
及び
##
)や例外処理 (
#
などで
必要となる。
一般ユーティリティ部品群は,動的記憶域管理用にあらかじめ定義された記憶域割付け子(
)
)など ,他のライ
ブラリの要素によって用いられる要素を含む。診断機能部品群は,
"##
においてエラーを報告するための首尾一貫
したフレームワークを提供する。これには,あらかじめ定義された例外クラスも含まれる。
文字列部品群は,
型のデータ列,
<
型のデータ列,又は
:
文字様
;
の型のデータ列として表現されたテ
キストの操作機能を提供する。現地化部品群は,そのようなテキスト処理に関する国際化支援機能を拡張する。
コンテナ部品群,反復子部品群 及び アルゴ リズム部品群は,
"##
プログラムに,広く使われているアルゴ リズ
ム 及び データ構造を提供する。
数値処理部品群( 複素数を含む。)は,
"##
言語の数値処理機能を拡張する。その一つの部品
は,一度
に
個の処理を行う機能を提供する。このような処理は,並列処理が実行可能な処理系では,並列処理を用いて実装
することができる。
入出力部品群は,
"##
プログラムが入出力を行うための基本的な機構を提供する。これらは,文字列部品群,現
地化部品群,反復子部品群などの要素とともに用いることができる。
"##
標準ライブラリは,静的な型安全性を保証する修正を施した標準
"
ライブラリの呼出しも可能にしている。
)
〜
)
では,専門用語の定義(
)
),用語一般の定義(
)
)及び ライブラリの記述方法
)
)を規定
する。
)
及び
〜
)
では,ライブラリの内容,並びに 適格な
"##
プログラム 及び 規格合致処理系の両者に
対する,ライブラリの要件 及び 制約を規定する。
)
専門用語の定義
)
任意位置ストリーム (
%!
)
ストリーム(
)
で規定する。)の範囲内において,
任意の整数値位置にシーク可能なストリーム。すべての任意位置ストリームは,位置復元可能ストリーム(
)(
)
でもある。
)
文字
&
,
及び
)
において,文字とは,順処理でテキストを表現することができる任
意のオブジェクトを意味する。この用語は,
オブジェクト 及び
<
オブジェクトだけでなく,
,
及
び
)
における定義を満足する型によって表現可能なすべての値を意味する。
)
文字コンテナ型
&
文字(
)
)を表すために用いられるクラス 又は 型。
これは,文字列クラステンプレート 及び 入出力ストリームクラステンプレートのテンプレート仮引数の一つとして
用いられる。文字コンテナ型は,
"
互換(
*
)型でなければならない。
)
比較関数
"
等価演算子(
#
)及び 比較演算子(
#*
)を表す演算子関数(
#
)
。
)#
部品群
ライブラリ内で定義された実体の集合で,メンバ,仮引数,又は 返却値の型として
直接的に関連するもの。例えば ,クラステンプレート
,及び 文字列に対して操作を行う非メンバ関数
テンプレートは,文字列部品群として参照される。
)(
省略時動作
"
%
&
'
未実装ライブラリ関数 及び ハンド ラ関数の意味記述。必す( 須)動作
の範囲内で,処理系によって提供された特定の動作。
))
ハンド ラ関数
&
"
その定義が
"##
プログラムによって提供される可能性のある非予約
済み関数。
"##
プログラムは,実行中の様々な時点においてハンド ラ関数を指定することができる。これは,ハンド
ラ関数を取り込むライブラリ関数を呼ぶ際に,ハンド ラ関数へのポインタを渡すことによって行われる(
参照)
。
)
入出力スト リームクラステンプレート
)
で定義された,
及び
という二つのテンプレート仮引数をもつテンプレート。
には,文字コンテナクラスを実引数として与え
る。
には,
によって表される文字型の入出力ストリームクラステンプレートを実装する際に必要とされ
る,追加の性質 及び 関数を定義する構造体を実引数とする。
)*
変更関数
$
"
クラスのメンバ関数(
*
)で,そのクラスのオブジェクトの状態を変更
するもの。ただし ,コンストラクタ,代入演算子,デストラクタを除く。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
)
オブジェクト の状態
%
/
オブジェクト(
*
)が保持する,すべての非静的なクラスメンバ
の現在の値。オブジェクトの状態は,一つ以上の観測関数を使って得ることができる。
)
ナロー文字単位スト リームクラス (
+!
)
入出力ストリームクラステ
ンプレートに対して,文字コンテナクラスとして
を与え,仮引数
に省略時の値を与えて具現したクラ
ス。従来の入出力ストリームクラスは,ナロー文字単位入出力ストリームクラス(
)
)だと見なせる。
)
011
文字型の値の列で,列を終端する文字型値ナル(
の返却値)の前に存在するもの。
)
観測関数
%'
"
オブジェクトの状態にアクセスするクラスメンバ関数(
*
)
。オブジェ
クトの状態を変更することはない。オブザーバ関数は,
メンバ関数(
*
)として指定される。
)
未実装ライブラリ関数
"
"##
プログラムによってその定義が与えられる非予
約済み関数。,プログラムを生成(
)し ,すべての翻訳単位の定義を解決(
#
)した結果として,選ばれた唯一
の定義がプログラムの実行期間中を通じて有効となる。
)#
必す( 須)動作
2
%
&
'
未実装ライブラリ関数 及び ハンド ラ関数の意味記述。これは,
処理系が提供する動作にも,プログラム中の関数定義によって提供されるべき動作にも適用する。
"##
プログラム
中で定義された関数が実行中に必す( 須)動作を満足しなかった場合,そのプログラムの動作は,未定義となる。
)(
位置復元可能スト リーム
以前に停止した位置に対してだけシーク可能なスト
リーム(
)
で規定する。)
。
))
予約済み関数
'
"
標準
"##
ライブラリの一部として指定されていて,処理系によって
定義されなければならない関数。
"##
プログラムが予約済み関数の定義を与えた場合,その結果は,未定義とする。
)
特性クラス
型 及び 関数の集合をカプセル化したクラス。このクラスが定義する型 及び
関数は,クラステンプレート 及び 関数テンプレートが,具現化の際に与えられた型のオブジェクトを操作するのに
必要となる。
,
及び
)
で定義された特性クラスは, 文字特性と呼ばれ,文字列部品群 及び 入出力ストリー
ム部品群で必要となる文字操作支援機能を提供する。
)*
ワイド 文字単位の入出力スト リームクラス (
+!
)
入出力ストリームク
ラステンプレートに対して,文字コンテナクラスに
を与え仮引数
に省略時の値を与えて具現化した
クラス。
)
用語一般の定義
この規格で用いる一般の用語定義は,
による。
)
記述方法( 参考)
)
では,標準
"##
ライブラリを記述する際の取決めを,ライブラリを規定する
〜
)
の構造(
)
)と記述形式に付いての取決め(
)
)とに分けて示す。
)
ライブラリ記述の構造
標準
"##
ライブラリの内容の要約を,
)
に示す。
表
に示すとおり,各ラ
イブラリ要素に対する詳細を
〜
)
に規定する。
表
ライブラリの分野
章
分野
言語常備
診断機能
一般ユーティリティ
文字列
現地化
コンテナ
反復子
アルゴ リズム
数値処理
入出力
ライブラリ節は,それぞれ,次の要素で構成する。
―
要約
―
要件
―
詳細仕様
注
紙面節約のため,必要でない項目は省略する。例えば,要件を規定しないライブラリ節には,
要件
要素がない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
―
標準
"
ライブラリへの参照
)
要約
要約項目は,そのライブラリ要素を要約し ,その最上位レベルでの箇条の一覧を示す。各箇条には,
また,その箇条の中で規定するヘッダ 及び 各ヘッダで提供されるライブラリ実体を一覧する要約を置く。
:
参考
;
又は
:
例
;
とラベル付けされた段落は,参考のための段落とし ,その他の段落は,ライブラリを規定する段
落とする。
要約項目 及び 詳細規定項目は,次の順序で記述する。
―
マクロ
―
値
―
型
―
クラス
―
関数
―
オブジェクト
)
要件
ライブラリは,
"##
プログラムによって拡張することができる。各箇条は,そのような拡張が可
能な場合,拡張が満足しなければならない要件を規定する。このような拡張は,通常,次のいずれかでなければなら
ない:
―
テンプレートの実引数
―
派生クラス
―
インタフェースの取決めを満足する,コンテナ,反復子 及び/又は アルゴ リズム
文字列部品群 及び 入出力ストリーム部品群は,必要とされる操作の明示的な表現をテンプレート 実引数にとる。
これらの制約条件を定義するために,クラステンプレート
を用いる。
イン タフェースの取決めに関する要件は ,可能な限り一般的に記述する。例えば ,
:
クラス
5
は ,メンバ関数
))
を定義していなければならない
;
と書かずに,
:
クラス
5
のすべてのオブジェクト
に対して,
))
が定義されている
;
という形で書く。すなわち,演算子が メンバかど うかは,規定しない。
要件は,適切に定義された式の形で記述する。この式は,要求を満足する型における有効な条項を定義する。すべ
ての要求の集合に対し,有効な式の集合とその意味を表形式(
#
,
及び
参照)で規定する。はん(汎)
用アルゴ リズム(
#
)に対する要求は,その仮引数型に対して有効な式の形を与えることによって与える。
テンプレート実引数に対する要求が,その名前によって示される場合もある(
)
参照)
。
意味的要求が
"##
のコード で記述される場合もある。そのようなコード は,構成要素間における同等性の記述を
意図しており,示されたコード のとおりにその構成要素を実装する必要はない。
)
仕様
詳細仕様は,次の要素を含む。
―
名前と簡単な説明
―
概要( 適切な場合には,クラス定義 又は 関数原型)
―
テンプレート実引数に対する制約( 必要な場合)
―
クラス不変式の記述
―
関数の意味の記述
クラスメンバ関数の記述は,次の順に行う。
―
コンストラクタ 及び デストラクタ
―
コピー関数 及び 代入関数
―
比較関数
―
変更関数
―
観測関数
―
演算子 及び 非メンバ関数
関数の意味の記述は,次の要素を含む。
―
要件
関数を呼ぶ際の事前条件
―
効果
関数が実行する動作
注
ただし ,示されたコードが最適な実装であることが明らかな場合もある。
注
これらの仕様の形式は,既存の
ライブラリ供給者によって確立された慣習に従っている。
注
紙面節約のため,そのクラスにあてはまらない項目は省略する。例えば,そのクラスが比較関数を指定しない場合,
比較関数
の項
目は,存在しない。
注
紙面節約のため,その関数にあてはまらない要素は省略する。例えば ,そのクラスが追加の事前条件を規定しない場合,
事前条件
の要素は,存在しない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
―
事後条件
関数の実行によって得られた観察可能な結果
―
返却値
関数の返す値の記述
―
例外
関数が送出する例外,及び 例外を送出する条件
―
計算量
時間 及び 空間的な計算量
非予約済みの未実装ライブラリ関数 及び ハンド ラ関数について,
では,必す( 須)動作 及び 省略時動作とい
う,
種類の動作を規定する。省略時動作は,処理系が提供する関数定義を規定する。必す( 須)動作は,処理系 又
は
"##
プログラムのいずれかによって提供される関数定義の意味を規定する。この区別が明記してない場合は,必
す( 須)動作とする。
ライブラリ箇条に規定する計算量に対する要件は,上限値で規定する。処理系は,それに優る計算量を保証してい
れば ,この要件を満足する。
)
ライブラリ
参照
の段落には,関連するこの規格の箇条 及び
6
の関連箇条への参照を示
す。
6
の関連箇条とは,この規格の規定となる箇条をいう。
)
他の取決め
)
では,標準
"##
ライブラリの記述に用いる編集上の取決めを規定する。これらの取決
めは,処理系定義の型(
)
)及び メンバ関数(
)
)に関係する。
)
型の記述
要件の箇条では,テンプレート実引数に対する制約の記述用に名前を導入して用いる。
これらの名前は,
,
,
#
及び
(
で,ライブラリの中のテンプレート部品を
"##
プログラムから具現す
る際に,与えることのできる実引数の型を規定するのに用いられる。
)
では,処理系定義の型を表すための型名を導入する。これの型は,他の型に基づくものの,何らかの制約条件
が付け加わる。
)
被列挙型
)
は,幾つかの型を被列挙型として定義する。これらの被列挙型は,列挙体で実装しても
よいし ,列挙体と同等な方法で実装してもよい。
こうした被列挙型
は,例えば ,次の方式で実装することができる。
QH.
HL
H+
H*
(((((R&
7.H. &
7LHL &
7+H+ &
7*H* &
(((((
ここで,
7.
や
7L
などの名前は,この特定の被列挙型の列挙要素を表す。この列挙要素は,すべて異なる値をもつ。
)
ビット マスク型
)
では,幾つかの型をビットマスク型として定義する。これらのビットマスク型は,
ここに示す演算子を多重定義した列挙型,整数型 又は
(
#
)として実装してよい。
こうしたビットマスク型
は,例えば ,次の方式で定義することができる。
Q
H.
%
L
.
HL
%
L
L
H+
%
L
+
H*
%
L
*
(((((
R&
7.H. &
7LHL &
7+H+ &
7*H* &
(((((
0
5
J
''
説明のためだけ。
''
P
は,
のすべての値を表現可能な整数型とする。
Q
P
PP
5
0
PP
J
&
R
1
5
J
Q
P
注
からの例:
*=$7.
,
> ?7.
,
77$.
など 。
からの例:
$
,
5&
,
5$
,
@&
など 。
注
例えば,宣言された定数名をもつ整数型(
)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
PP
5
1
PP
J
&
R
W
5
J
Q
P
PP
5
W
PP
J
&
R
X
5
Q
P
P
P
X5
&
R
0
0%
0
5
J
Q
5
%
5
0
J&
5&
R
0
1%
0
5
J
Q
5
%
5
1
J&
5&
R
0
W%
0
5
J
Q
5
%
5
W
J&
5&
R
ここで,
7.
,
7L
などの名前は,この特定のビットマスク型に対するビットマスク要素を表す。このような要素は,
すべて異なる値をもつ。すなわち,任意の
と
のペアについて,
0
は非ゼロとなり,
0
はゼロとなる。
ビットマスク型のオブジェクト 及び 値に関し ,次に示す用語を用いる。
―
値
でオブジェクト
をセットするとは,式
1%
を評価することをいう。
―
値
でオブジェクト
をクリアするとは,式
0%
X
を評価することをいう。
―
値
がオブジェクト
にセットされているとは,式
0
がゼロでないことをいう。
)
文字の列
標準
"
ライブラリは,文字 及び 文字の列を,広範に利用している。この文字 及び 文字の列
は,次の幾つかの統一的な取決めに従う。
―
英字
とは,基本実行文字集合中の,
個の英小文字 及び
個の英大文字の中のいずれかの文字
をいう。
―
小数点文字(
3-1
)とは,
(
バイト )文字の一つとし,
(
バイト )文字の列と浮動小数
点型の値との変換を行う関数で用いられ,文字の列の中で小数部の先頭を示すのに使われる文字とする。
〜
)
では,これを,
Y7Y
現地特性における値でもあるピリオド
Z(Z
で表している。しかし ,小数点
文字は,
!
の呼出し ,又は 現地特性オブジェクトの変更(
及び
)
参照)によってプログラム実行中に変わる可能性がある。
―
文字の列
!A
とは,
S
T
と宣言可能な配列オブジェクト(
)
をいう。ここ
で,
は,
,
又は
(
*
)のいずれかとし ,
又は
で修飾してあってもよい。この配列の先頭要素から,何らかの条件によって決定される要素まで(その要
素も含む。)の範囲内が,内容を与える。文字の列は,先頭要素をさすポインタ値
で示すこともできる。
)
バイト 文字列
)+4/
(
-3
%
!
,ナル文字で終端されたバイト文字列)は,最も
高位アドレスの要素の値がゼロ( 終端ナル文字)であるような文字の列とする。
)
+
4
/
の長さ
)+4/
は,終端ヌル文字より前の要素数となる。空の
)
+
4
/
1
)+4/
の長さは,
とする。
)+4/
の値
0
)+4/
は,終端ヌル文字まで( 終端ヌル文字も含む。)の要素の値の列とする。
静的
)+4/
!
)+4/
は,静的記憶域期間を有する
)+4/
とする。
)
多バイト 文字列
)
+
'
4
/
(
-3
%
!
,ナル文字で終端された多バイト文字列
)は,正当な多バイト文字の列をなす
)+4/
とする。この列は,初期シフト状態で始まり,初期シフト状態で終わる。
静的
)+'4/
!
)+'4/
は,静的記憶域期間を有する
)+'4/
とする。
)
ワイド 文字の列
ワイド 文字の列(
<3-
!A
)は,
S
T
と宣言可能な配列オブジェ
クト(
)
とする。ここで,
は,
(
*
)型であり,
又は
で修飾することができ
る。配列の初期要素は,ある述語によって決定される要素まで(その要素も含む。)の内容を定義する。文字の列は,
先頭要素をさすポインタ値
で示すこともできる。
注
この定義は,
の
の定義と異なることに注意。
注
(
)で宣言されている。
注
4
(
)で宣言された関数によって操作される多くのオブジェクトは,文字の列 又は
012
である。文字の列の大きさ
は,文字の列とは別に維持する文字列長値によって制限されることもある。
注
.
のような文字列リテラルは,静的
012
である。
注
基本実行文字集合の文字だけを含む
012
は,
0132
でもある。この場合,すべての多バイト文字が
バイトとなる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
##
)+C"/
(
-3
<3-
!
,ナル文字で終端されるワイド 文字文字列)は,最も高位アドレ
スの要素の値がゼロであるようなワイド 文字の列とする。
)
+
C
"
/
の長さ
)+C
"/
は,終端ナルワイド 文字より前の要素数とする。空
)
+
C
"
/
1
)+C
"/
の長さは,
とする。
)+C"/
の値
0
)+C
"/
は,終端ナルワイド 文字まで( 終端ナルワイド 文字も含む)の値の列とする。
静的
)+C
"/
!
)+C
"/
は,静的記憶域期間を有する
)+C
"/
とする。
)
クラス内の関数
説明の都合上,
〜
)
の記述では,省略時に生成される(
,
及び
)も
のと同等な意味を有するコピーコンストラクタ,代入演算子,
( 非仮想の )デストラクタについて記述しない。
このようなメンバ関数呼出し情報 又は 省略時に生成されうる仮想デストラクタに対し ,処理系が明示的な定義を
与えるかど うかについては,未規定とする。
)
非公開メンバ
〜
)
では,クラスの表現を規定しない。したがって,クラスメンバ(
*
)の仕様を
意図的に省略している。処理系は,
〜
)
に規定されたメンバ関数の意味を実装するため,必要なだけの静的 又
は 非静的なクラスメンバを定義してよい。
クラスによっては,そのクラスの外部仕様の中で,データを格納する,そのメンバオブジェクトにされる必要が生
じる場合がある。説明の都合上,箇条によっては,このクラス外部仕様を充足する非公開メンバオブジェクトに対し
て,その典型的な宣言を与え,意味的な要件を与えることがある。このようなメンバオブジェクトの宣言 及び それ
に関連するメンバ型の定義は,次の例のように注釈として書き,更に
:
説明のためだけ
;
と注を付けてある。
''
!
&
説明のためだけ
外部から見て同等な動作を行う実装は,これに限らず,どんなものでも許される。
)
ライブラリ全体に対する要件
)
では,標準
"##
ライブラリ全体に適用される要件を規定する。
〜
)
では,ライブラリごとの要件を規定する。
)
の構成を,次に示す。
―
ライブラリの内容 及び 構成
)
―
適格な
"##
プログラムがライブラリ実体にアクセスする方法
)
―
そのようなプログラムに対する制約
)
―
規格合致処理系に対する制約
)
)
ライブラリの内容 及び 構成
)
は,標準
"##
ライブラリで定義されている実体の要約を示す。
)
には,実体の種類を列挙し ,
)
にはライブラリヘッダを列挙する。
)
ライブラリの内容
標準
"##
ライブラリは,次の種類の構成要素を有する。
―
マクロ
―
値
―
型
―
テンプレート
―
クラス
―
関数
―
オブジェクト
マクロ 及び 演算子
・
を除く,すべてのライブラリ実体は,名前空間
,又は それに入れ子になった
名前空間の中で定義される。
)
ヘッダ
"##
標準ライブラリの構成要素は,ヘッダの中で宣言されるか定義される。
"##
標準ライブラリは,
表
に示す
個の
"##
ヘッダを提供する。
注
?
で宣言された関数によって操作される多くのオブジェクトは,ワイド 文字の列 又は
A72
とする。
注
>.
のようなワイド 文字列リテラルは,静的
014
である。
注
ヘッダがソースファイルである必要はない。更に,ヘッダ 名の
及び
で囲まれた列が正当なソースファイル名である必要もない
(
参照)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#(
表
,,
ライブラリヘッダ
標準
"
ライブラリの機能は,
表
に示す
個のヘッダで提供する。
表
ライブラリ機能のための
,,
ヘッダ
-M-
〜
)
で規定する点を除き,
:;
というヘッダは,
6
プログラム言語
"
の
)
又は
6
&'()*'()+
プログラム言語
"
( 追補
)の
)
による
:(;
というヘッダの内容に
等しい。しかし ,
"##
標準ライブラリの場合,宣言 及び 定義は,
(
"
のマクロとして定義された名前を除き)名前
空間
の名前空間有効範囲(
#
)内に存在する。
"##
標準ライブラリでは,
"
でマクロとして定義されている名前は,
"
で関数として実装することが許されてい
るものであっても,マクロとして定義する。
参考
"
でマクロとして定義されている名前には,
,
,
,
,
,
及
び
を含む。
"
で関数として定義されている名前は,標準
"##
ライブラリでも関数として定義する。
附属書
5
の
5#
標準
"
ライブラリヘッダの箇条に,
"##
プログラム内で
:(;
の形式のヘッダを用いた場
合の効果が規定してある。
)
自立処理系
次に挙げる
種類の処理系が定義されている(
)
。
―
依存処理系
―
自立処理系
この規格は,依存処理系で用いることが可能なヘッダを規定する。
自立処理系は,処理系定義のヘッダ群を提供する。この中には,少なくとも
表
に示すヘッダが含まれていなけ
ればならない。
表
自立処理系のための
,,
ヘッダ
節
ヘッダ
型
処理系特性
開始 及び 終了
動的記憶域管理
#
型の識別
+
1
3
>
(
例外処理
)
その他の実行時機能
更に,
には,少なくとも
,
及び
(
)が宣言されていなければならない。
注
これは,関数プロトタイプに加えて
マスキングマクロ
を提供するという,
では認められていた慣行を禁止している。
にお
いて,同様なインライン的挙動を実現するには,外部インライン関数として定義を提供することしかない。
注
0?
ヘッダは,そこで定義されたすべての名前を大域的名前空間に入れる。これに対し ,新しい形式のヘッダは,そこで定義された
名前を名前空間
&
に入れる。したがって,
との厳密な互換性を必要とするプログラムを除き,新しい形式のヘッダを用いることが望
ましい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#)
)
ライブラリの使用法
)
では,
"##
プログラムが
"##
標準ライブラリの各機能を利用する方法を規
定する。
)
では翻訳段階
における効果を規定し ,
)
では翻訳段階
における効果を規定する。
)
ヘッダ
"##
標準ライブラリに含まれる実体は,ヘッダ 内で定義される。ヘッダの内容は,適切な前処
理指令
(
(
)を,その翻訳単位に含めることで利用する。
翻訳単位は,ライブラリヘッダをどのような順序で取り込んでもよい(
参照)
。各ヘッダは,複数回取り込んで
よい。複数回取り込んでも,
回だけ取り込んだ場合と効果に変わりがない。ただし ,
及び
(
は例外であって,その取込みの効果は,取り込む時点での
A#8"G:
の字句的定義内容に依存する。
翻訳単位でのヘッダ取り込みは,すべての外部宣言 又は 定義の外側で行わなければならない。ヘッダ内で,宣言
されるか 又は 最初に定義されるかした実体への参照を含む翻訳単位では,その単位内でのそうした最初の参照の前
に,そのヘッダの取り込みを行わなければならない。
)
結合
"##
標準ライブラリの実体は,外部結合(
#
)をもつ。特に規定しない限り,オブジェクト 及び
関数は,
Y7))Y
という結合(
)#
)を省略時解釈としてもつ。
標準
"
ライブラリの中で,外部結合をもつと宣言された名前が,
Y7Y
結合 又は
Y7))Y
結合をもつ
かいなかは,処理系定義とする。
この点に関し ,処理系が
Y7))Y
結合を用いることを推奨する。
ライブラリ中で定義され,
"##
プログラムが必要とするオブジェクト 及び 関数は,プログラム実行開始前に取り
込まれる。
参照
未実装ライブラリ関数(
)
) 及び 実行時の変更(
)#
)
。
)
プログラムに対する制約
ここでは,
"##
標準ライブラリの機能を利用する
"##
プログラムに対する制
約を,次に示す項目に分けて規定する。
―
プログラムの名前空間
)
―
ヘッダの使用法
)
―
標準ライブラリクラスからの派生クラス
)
―
未実装ライブラリ関数の定義
)
―
実行時におけるハンド ラ関数の組込み
)#
)
予約名
特に規定する場合を除いて,
"##
プログラムが,名前空間
又は 名前空間
内の名前空
間に対して,宣言 又は 定義を追加することの効果は,未定義とする。プログラムが,名前空間
に対し ,標準ラ
イブラリテンプレートの特殊化を追加することは,許されている。このような標準ライブラリテンプレートの特殊化
( 完全でも部分でも)をした場合,その宣言が外部結合の利用者定義名に依存していないとき,及び その特殊化が元
のテンプレートに対する標準ライブラリの要求を満足していないときには,その動作は未定義とする。
"##
標準ライブラリは,次に示す種類の名前を予約する。
―
マクロ
―
外部名
―
外部結合をもつ名前
)
で明示的に許容するときを除き,予約名が有効な文脈において,プログラムが予約名と同じ名前を宣言 又
は 定義した場合,その動作は未定義とする。
)
マクロ名
ヘッダ中でマクロとして定義された名前は,翻訳単位がそのヘッダを取り込んだ場合,いか
なる用途に対しても,処理系用に予約する。
ヘッダを取り込んだ翻訳単位は,そのヘッダ中で宣言 又は 定義された名前を定義するマクロを含んでいてはなら
ない。更に,そのような翻訳単位は,字句的にキーワード と一致する名前をマクロとして定義してはならない。
)
大域名
次に示す名前 及び 関数呼出し情報は,常に処理系用に予約する。
―
個の下線(
)を含む名前,又は
個の下線で始まりその後に大文字が続く名前(
)は,いかなる
使用も,処理系用に予約される。
―
下線で始まる名前は,大域的名前空間における名前として,処理系用に予約する。
注
これは,標準
ライブラリと同じである。
注
標準
の
で認められた許容範囲にかかわらず,標準
ライブラリに含まれるオブジェクト 又は 関数呼出し情報を宣言するた
めの唯一の信頼できる方法は,それを宣言しているヘッダを取り込むことである。
注
他のライブラリテンプレートを具現するライブラリコードは,標準が規定する最小限の要件を満足する利用者提供の特殊化に対し,適
切に動作するよう準備されなければならない。
注
ライブラリのマクロ定義は,
9$&%
指示子を用いて除去しようとしてはならない。
注
そのような名前は,名前空間
&
(
)でも予約されている。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
)
外部結合
外部結合をもつオブジェクトとしてヘッダ中で宣言された名前は,名前空間
及び 大域的
名前空間内においてその外部結合をもつライブラリオブジェクトを表すために,処理系用に予約する。
ヘッダ中で宣言された外部結合をもつ大域的関数呼出し情報は,その関数呼出し情報が外部結合をもつことを表す
ために,処理系用に予約する。
個の連続した下線を含む名前(
)は,
Y7Y
及び
Y7))
Y
結合の両者をもつ名前として,処理
系用に予約する。
外部結合をもつとして宣言された標準
"
ライブラリの名前は,名前空間
及び 大域的名前空間の両者において,
Y7Y
結合をもつ名前として,処理系用に予約する。
外部結合をもつとして宣言された標準
"
ライブラリの関数呼出し情報は,
Y7Y
及び
Y7))
Y
結合
をもつ関数呼出し情報として,又は 大域的名前空間内の名前空間範囲の名前として,処理系用に予約する。
)
型
を標準
"
ライブラリ内の型とするとき,
33
及び
33
は,処理系用に予約する。
33
が定
義されている場合,
33
と同一とする。
)
ヘッダ
"##
標準ライブラリヘッダの派生ファイル名と等しい名前をもつファイルが処理系の一部とし
て提供されず,ソースファイルが取り込まれる標準的な場所
(
に,その名前のファイルが存在する場合,その動
作は未定義とする。
)
派生クラス
"##
標準ライブラリ内の基底クラスで定義された仮想メンバ関数呼出し情報は,それを基
底としてプログラム内で定義したその派生クラスの中で,上書きしてよい(
)
。
)
未実装ライブラリ関数
〜
)
では,
"##
標準ライブラリで定義された多くの関数の動作を規定する。
しかし ,これらの関数記述のいくつかは,状況に応じてプログラム中で定義された未実装ライブラリ関数(
)
)に
も適用される。
"##
プログラムは,次に示す
個の動的記憶域割付け・解放関数の呼出し情報(これらは,ヘッダ
で宣言
されている。)の定義を提供してもよい(
)
及び
参照)
。
―
$
―
$
33
0
―
ST$
―
ST$
33
0
―
!
―
!
33
0
―
ST!
―
ST!
33
0
これらの定義が提供された場合,処理系が提供する省略時の定義(
)に代えて,プログラムが提供した定義が
用いられる。このような置き換えは,プログラムの実行が開始される前に行われる(
及び
(
参照)
。
)#
ハンド ラ関数
"##
標準ライブラリは,次のハンド ラ関数(
)に対し,省略時の版を提供する。
―
―
"##
プログラムは,次に示す関数に,プログラム 又は ライブラリ中で定義された関数へのポインタを実引数と
して渡すことによって,実行中に異なるハンド ラ関数を組み込むことができる。
―
―
―
参照
記憶域割付けエラー,
(
例外処理
)(
その他の関数
ある種の場合( 未実装ライブラリ関数,ハンド ラ関数,標準ライブラリのテンプレート要
素を具現化するのに使われた型に対する操作など ),
"##
標準ライブラリは,
"##
プログラムが提供する要素に依
存する。このような要素がその要件を満足しない場合,この規格は,処理系に対して何の要求も行わない。
注
こうした予約名には,
中で宣言 又は 定義されている
がある。
注
こうした外部結合をもつ予約関数呼出し情報には,
B
で宣言 又は 定義されている
BB
.$%
,及び
&4
で
宣言 又は 定義されている
&
がある。
注
?
及び
で宣言された関数呼出し情報は,常に処理系用に予約する。それらのヘッダに関する
の課す制限(
追補
の
)によらない。
注
としては,
C
,
&
,
5>*
,
%
,
,
&
,
.
,
&%%
,
4
,
-
,
,
,
,
,
及び
0
がある。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#*
特に,次のような場合,その効果は未定義とする。
―
未実装ライブラリ関数(
)について,組み込まれた未実装ライブラリ関数が,
要件
に書かれた意味
を実装していない場合。
―
ハンド ラ関数(
,
(
及び
(
)について,組み込まれたハンド ラ関数が,
要件
に書
かれた意味を実装していない場合。
―
テンプレート要素を具現化する際に用いた型について,その型に対する操作が
要件
(
#
,
,
及び
(
)に書かれた意味を実装していない場合。特に規定しない限り,そのような型に対する操作は,
例外送出によって通知される。
―
未実装ライブラリ関数,ハンド ラ関数 又は デストラクタ操作が例外を送出する場合。ただし ,
要件
で明
示的に許可されている場合を除く。
―
テンプレート要素の具現化において,不完全型(
*
)をテンプレート実引数として用いた場合。
))
関数実引数
特に明記しない限り,
"##
標準ライブラリで定義された全関数の実引数には,次のことが
らを適用する。
―
関数の実引数が不正な値( 関数の定義域を外れる値,又は 想定された用途には無効なポインタ値)の場合,
その動作は未定義とする。
―
関数の実引数を配列と指定している場合,実際に関数に渡されるポインタは,すべてのアドレス計算 及
び オブジェクトに対するアクセス(これらは,そのポインタが配列の先頭要素を指していれば ,有効とな
る。)が有効となる値でなければならない。
)
要件の段落
関数の
要件
の段落に示す事前条件に反する場合,その動作は未定義とする。ただし,
例外
の
段落で,そのような条件に対して送出する例外が規定されている場合を除く。
)
規格合致処理系
)
では,次に示す項目によって
"##
標準ライブラリの処理系に対する制約 及び 許
容度について規定する。
―
ヘッダ
)
―
マクロ
)
―
大域的関数
)
―
メンバ関数
)
―
再入可能性
)#
―
アクセス記述子
)(
―
クラスの派生
))
―
例外
)
)
ヘッダ
"##
ヘッダは,他の
"##
ヘッダを取り込んでもよい。
ある種の型 及び マクロは,複数のヘッダで定義される。そのような要素を定義する
番目 及び それ以降のヘッダ
は,最初の定義を提供するヘッダの後で取り込んでもよい(
)
。
ヘッダの取込みに関して,次の制約を設ける。
―
"
ヘッダ [
(
の形式のヘッダ(
附属書
5
,
5#
参照)]から取り込むのは,対応する
"##
ヘッダだけ
でなければならない(
)
)
。
)
マクロ定義に対する制約
)
に規定する名前 及び 大域的関数呼出し情報は,処理系用に予約する。
特に指定しない限り,標準
"
ライブラリで定義されたオブジェクト形式マクロで,
)
で汎整数の定数式に拡張す
るものとして規定するマクロは,前処理指令
の中で用いることができる。
)
大域的関数 又は 非メンバ関数
"##
標準ライブラリに含まれる大域的関数 又は 非メンバ関数が,イン
ライン関数(
)
)として定義されるかど うかは,未規定とする。
〜
)
で規定する大域的関数呼出し情報 又は 非メンバ関数呼出し情報を呼び出した場合,処理系が追加の大域
的関数呼出し情報 又は 非メンバ関数呼出し情報を定義していない場合と同じ動作としなければならない。
処理系は,省略時実引数を追加した形で大域的関数 又は 非メンバ関数を宣言してはならない。
)
メンバ関数
"##
標準ライブラリに含まれるメンバ関数が,インライン関数として定義されるかど うか
は,未規定とする(
)
)
。
注
ヘッダは,必要な定義(
)を含むヘッダを取り込まなければならない。
注
正当な
プログラムは,常に期待ど おりのライブラリ大域的関数 又は ライブラリ非メンバ関数を呼び出す。処理系は,正当な
プログラムから呼び出されることのない追加の大域的関数 又は 非メンバ関数を定義してよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
処理系は,非仮想メンバ関数呼出し情報を,クラス内に次のとおりに追加してよい。
―
メンバ関数呼出し情報に省略時値を伴う実引数を追加する
。しかし ,このことは,仮想関数,大域的
関数 又は 非メンバ関数の実装には適用されない。
―
省略時値を伴うメンバ関数呼出し情報を,同等な動作をする複数のメンバ関数に置き換える。
―
同じ メンバ関数名に対してメンバ関数呼出し情報を追加する。
"##
標準ライブラリのメンバ関数呼出し情報を呼び出した場合,その動作は,処理系が追加のメンバ関数を定義
していない場合と同じでなければならない。
)#
再入可能性
"##
標準ライブラリ内のどの関数が再入可能なサブルーチンでないかは,処理系定義とする。
)(
クラス内の保護
〜
)
で規定する関数呼出し情報 又は クラスが,
"##
標準ライブラリ内の他のク
ラスの
であるかど うかは,未規定とする。
))
派生クラス
"##
標準ライブラリ内のクラスが,他の( 処理系に予約された名前をもつ)クラスからの
派生クラスであるかど うかは,未規定とする。
"##
標準ライブラリ内の幾つかのクラスは,
"##
標準ライブラリ内の他のクラスから派生する。このとき,次の
要件をおく。
―
"##
標準ライブラリの中で,他のクラスから派生していると規定されたクラスの場合,そのクラスが直
接派生しているか,指定された基底クラスから派生した他の( 処理系に予約された名前をもつ)クラスを
介しているかど うかは,未規定とする。
いずれにしても,次のことがらが成り立つ。
―
であると規定された基底クラスは,常に仮想基底クラスである。
―
非
であると規定された基底クラスは,仮想基底クラスにならない。
―
特に規定しない限り,異なる名前の型は,異なる型に対応する。
)
例外処理に関する制約
"##
標準ライブラリで定義された関数は,
例外
の段落 及び/又は その《例外指
定》
(
#
)に記す例外を送出することによって,その失敗を通知することができる。処理系は,そこに並べられた
例外の幾つかを除くことによって,非仮想関数の《例外指定》を強化してよい。
標準
"
ライブラリで定義された関数は,例外によってエラーを通知してはならない。
ただし ,その関数が,プログラムで提供された,例外を送出する関数を呼び出す場合は,この限りでない。
"##
標準ライブラリ中のデストラクタ操作は,どれも例外を送出しない。
"##
標準ライブラリのその他の関数
で,
《例外指定》をもたないものは,特に規定しない限り,処理系依存の例外を送出してもよい。
処理系は,暗黙的な《例外指定》の代わりに,明示的な《例外指定》を与えて強化してよい。
言語常備ライブラリ
では,
"##
プログラムの実行中に,暗黙に呼び出される関数の呼出し 情報,及び
暗黙に生成されるオブジェクトの型について規定する。更に,これらの関数の呼出し情報の宣言,及び 関連するデー
タ型の定義をするヘッダを規定する。
〜
)
では,
表
に示すとおり,ライブラリを通して使われる共通の型定義,あらかじめ定義された型の特
性,
"##
プログラムの開始 及び 終了の機能をもつ関数,動的な記憶域管理の機能,動的な型識別の機能,例外処理
の機能,及び その他の機能を規定する。
注
したがって,メンバ関数のアドレスを取った場合,その結果の型は未規定となる。
注
正当な
プログラムは,常に期待ど おりのライブラリのメンバ関数 又は それと同等な動作を有するものを呼び出す。処理系は,
正当な
プログラムから呼び出されることのないメンバ関数の定義を追加してもよい。
注
この規則に対する暗黙の例外は,
-
(
),
%%
(
)などの,基本整数型の別名であると規定された型である。
注
すなわち,その関数の実装が標準の規定より少ない《例外指定》をもつことができる。しかし,
《例外指定》で指定された例外の型を変
更したり,例外を追加したりすることはできない。
注
すなわち,すべての
ライブラリ関数は,
?
の《例外指定》をもつ。これによって,処理系は,実行時の例外処理を省略して
性能を向上させることが許される。
注
=
及び
.?
(
)は,この条件を満たす。
注
特に,記憶域の割付けでの失敗を,
.&
型 又は
.&
から派生したクラス(
)の例外を送出することによって
通知してよい。ライブラリの実装は,標準例外クラス(
,
及び
)
(又は ,それらから派生したクラス)の例外を送
出することによってエラーを通知することが推奨される(ただし,これは要求ではない。)
。
注
すなわち,処理系は,その関数が送出するすべての例外の部分集合を定義する明示的な《例外指定》を提供してよい。これは,そのよ
うな《例外指定》において,処理系が,処理系定義の型を与えてよいことを意味する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
表
言語常備ライブラリの要約
箇条
ヘッダ
型
処理系特性
開始 及び 終了
動的な記憶域管理
#
型の識別
(
例外処理
)
その他の実行時機能
型
共通の定義を規定する。
ヘッダ
の一覧を
表
#
に示す。
表
#
ヘッダ
の一覧
種別
名前
マクロ
AG??
型
$
このヘッダの内容は,標準
"
ライブラリのヘッダ
(
と同じとする。ただし ,次の変更がある。
この規格でのマクロ
AG??
は,処理系定義の
"##
空ポインタ定数(
)となる
。
この規格でのマクロ
は,仮引数
!
$
に与えうる実引数に制限がある。与えうる実引数は,
"
互換構造
体 又は
"
互換共用体(
*
)に限られる。静的データメンバ 又は 関数メンバにマクロ
を適用した場合,そ
の結果は未定義とする。
参考
6
では,マクロ
の仮引数
!
$
を型と表現している。
#
$
,
#)
加減演算子,
#
空き領域,及び
6
(プログラム言語
"
)の
)(
を参照。
処理系特性
ヘッダ
,
及び
は,処理系依存の基本型(
*
)の特性を提供
する。
数値の限界
は,その処理系での基本型の表現の諸特性についての情報を
"##
プログラ
ムに提供する。
浮動小数点型 及び 整数型(
%
型を含む。)の基本型それぞれに対し ,
の特殊化が提供される。
これらの
の特殊化では,メンバ
$
を
としてある。
それぞれの特殊化では,テンプレート
の
として宣言されたメンバすべての値を,
整数定数式として使用できる形で定義してある。
基本型でない標準の型( 例えば
(
の
)には,特殊化は提供されない。
ヘッダ
の一覧を示す。
Q
P&
PP
&
PP
&
P
&
P
&
P
&
注
定義内容には,
)
及び
)>
があり得る。しかし ,
&)
はあり得ない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
P
&
P
P
&
P
&
P
&
P
&
P
&
P
&
P
&
P
&
P
&
P
&
R
クラステンプレート
Q
P
Q
3
P$
%
&
&
&
%
.&
L.
%
.&
P
%
&
P
%
&
P
%
&
%
.&
&
P
&
P
%
.&
PL.
%
.&
P
%
.&
PL.
%
.&
P
%
&
PPAA
%
&
PPAA
%
&
PP
P
%
P&
PP
%
&
&
PAA
&
PAA
&
P
&
P//O
%
&
P
%
&
P
%
&
%
&
P
%
&
PP
P
%
PP$
&
R&
R
特殊化が提供されている基本型と,特殊化が提供されていない非スカラ型とは,メンバ
$
によって
区別できる。
既定のテンプレート
は,すべてのメンバをもたなければならないが,それらの値は,ゼロ 又
は
となっている。
のメンバ
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
有限最小値
を返す。
非正規形式をもつ浮動小数点型の場合,正規化した正の最小値を返す。
[%
である特殊化,又は
%%
00
%%
である特殊化でだけ
意味をもつ。
有限最大値
を返す。
[%
である特殊化でだけ意味をもつ。
その型で誤差なしで表現可能な
進法での最大けた数を表す。
組込みの整数型の表現では,符号以外のビット数を表す。
組込みの浮動小数点型では,
進法での仮数部のけた数
を表す。
その型で誤差なしで表現可能な
進法での最大けた数
を表す。
[%
である特殊化でだけ意味をもつ。
符号付き型でだけ
となる。
すべての特殊化で意味をもつ。
整数型でだけ
となる。
すべての特殊化で意味をもつ。
正確な表現を行う型でだけ
となる。整数型はすべて正確であるが,正確な型がすべて整数であるとは限らな
い。例えば,有理数表現 及び 固定小数点表現は,正確であるが整数ではない。
すべての特殊化で意味をもつ。
浮動小数点型での指数部表現の基数( 多くの場合に
となる。)
を表す。
整数型の表現での基数
を表す。
すべての特殊化で意味をもつ。
機械エプシロン:
と
を超える表現可能な最小値との差
を表す。
すべての浮動小数点型で意味をもつ。
最大の丸め誤差
の大きさを表す。
注
7D"E
!5
2DE
!5
5>
!5
F,>
!
などのいずれかに等しい。
注
7D"E
!"#5
2DE
!"#5
5>
!"#5
F,>
!"#
などのいずれかに等しい。
注
5>
!"
FG5
F,>
!"
FG
又は
>F,>
!"
FG
に等しい。
注
5>
FG5
F,>
FG
又は
>F,>
FG
に等しい。
注
5>
E"F#
に等しい。
注
でない基数をとる型(例えば
,7F
)を区別する。
注
5>
*@2>H5
F,>
*@2>H
又は
>F,>
*@2>H
に等しい。
注
丸め誤差については,
6
* "
に規定されている[
及び
附属書
7
"
参照]
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
が正規化された浮動小数点数になる最小の整数
( 負数)
を表す。
すべての浮動小数点型で意味をもつ。
が正規化された浮動小数点数の範囲に入る最小の整数
( 負数)
を表す。
すべての浮動小数点型で意味をもつ。
が表現可能な浮動小数点数になる最大の整数
( 正数)
を表す。
すべての浮動小数点型で意味をもつ。
が,正規化された浮動小数点数の範囲に入る最大の整数
( 正数)
を表す。
すべての浮動小数点型で意味をもつ。
正の無限大に対する表現をもつ型でだけ
とする。
すべての浮動小数点型で意味をもつ。
//O
[%
である特殊化のすべてで,
となる。
非シグナル
-!,
A
))
)--)
%
に対する表現をもつ型
でだけ
とする。
すべての浮動小数点型で意味をもつ。
//O
[%
である特殊化すべてで,
となる。
シグナル
))!
)--)
%
に対する表現をもつ型
でだけ
とする。
すべての浮動小数点型で意味をもつ。
//O
[%
である特殊化すべてで,
となる。
非正規化値( 仮数部の有効ビット数が可変)を許す型
では
,非正規化値を許さない型では
とする。非正規化値を許すか否かがコンパイル時に不明の型では
とする。
すべての浮動小数点型で意味をもつ。
精度損失の検出が,不正確な結果に基づくのでなく,非正規化損失に基づく
型でだけ,
とする。
正の無限大の表現をもつ型
では,その表現を返す。
[%
であるすべての特殊化で意味をもつ。特に
//O
[%
である特殊化では,必
ず意味をもつ。
注
5>
!
*#@5
F,>
!
*#@
又は
>F,>
!
*#@
に等しい。
注
5>
!
+)
*#@5
F,>
!
+)
*#@
又は
>F,>
!
+)
*#@
に等しい。
注
5>
!"#
*#@5
F,>
!"#
*#@
又は
>F,>
!"#
*#@
に等しい。
注
5>
!"#
+)
*#@5
F,>
!"#
+)
*#@
又は
>F,>
!"#
+)
*#@
に等しい。
注
による。ここで,
とは,
をいう。
注
による。
注
による。
注
を参照。
注
による。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(#
非シグナル
))
に対する表現をもつ型
では,その表現を返す。
AA
[%
であるすべての特殊化で意味をもつ。特に
//O
[%
である特殊化では,必
ず意味をもつ。
シグナル
))
に対する表現をもつ型
では,その表現を返す。
AA
[%
であるすべての特殊化で意味をもつ。特に
//O
[%
である特殊化で
は,必ず意味をもつ。
正の最小非正規化数
を表す。
すべての浮動小数点型で意味をもつ。
%%
である特殊化では,正規化した正の最小値を返す。
(##*
に準拠している場合,かつその場合だけ
とする。
すべての浮動小数点型で意味をもつ。
その型の表す値の集合が有限である場合だけ
とする
。組込み型はすべて有限であり,これが
とな
るのは,任意の精度を許す型の場合だけである。
すべての特殊化で意味をもつ。
型がモジュラである場合にだけ,
とする
。型がモジュラであるとは,二つの正の値を加えた結果が,循
回してより小さな値になる可能性がある場合とする。
通常,浮動小数点型では
,符号なし整数では
となる。符号付き整数では,ほとんどの計算機で
と
なる。
すべての特殊化で意味をもつ。
割出し
が実装されている場合だけ
とする
。
すべての特殊化で意味をもつ。
丸めを行う前に微小値
が検出される場合にだけ
とする
。
すべての浮動小数点型で意味をもつ。
その型の丸めの様式を表す
。
すべての浮動小数点型で意味をもつ。整数型に対する特殊化では,
$
を返さなければならない。
注
による。
注
による。
注
による。
注
は,
と同一である。
注
による。
注
による。
注
による。
注
を参照。
による。
注
5>
EHIF2
に等しい。
による。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
((
型
Q
PP
Q
P
%
VL
PP$
%
.
PP
%
L
PP
%
+
PP
P
%
*
R&
R
浮動小数点型の計算における丸めモード は,次のいずれかの値とする。
―
丸めの様式を決定できない。
―
$
ゼロに向かって丸める。
―
表現可能な最も近い値に丸める。
―
無限大に向かって丸める。
―
負の無限大
に向かって丸める。
型
Q
PP
Q
P
%
VL&
P
%
.&
%
L&
R&
R
非正規化( 仮数部の有効ビット数が可変)の可否は,次の値とする。
―
非正規化された値を許すか否かを決定できない。
―
非正規化された値を許さない。
―
非正規化された値を許す。
#
の特殊化
いかなる特殊化においても,すべてのメンバを提供する。しかし ,多くの値
は,ある条件下でだけ意味をもつ( 例えば,
は,
が
の場合にだけ意味をもつ。)
。意味
をもたない値は,ゼロ 又は
に設定しなければならない。
例
Q
P
Q
3
P$
%
&
Q
L(L,/MOM*/8V*N9&
R
Q
*(M.+N+*M,8)*N9&
R
%
+M&
L.
%
-&
P
%
&
P
%
&
P
%
&
%
+&
Q
L(LO+.O+O.8V.,9&
R
P
Q
.(/9&
R
P
%
VL+/&
PL.
%
V
*,&
P
%
)L+N&
PL.
%
)
*N&
P
%
&
PPAA
%
&
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
()
PPA
A
%
&
PP
PP
%
P&
PP
%
&
Q
(((&
R
PAA
Q
(((&
R
PAA
Q
(((&
R
P
Q
&
R
P//O
%
&
P
%
&
P
%
&
%
&
P
%
&
PP
P
%
PP
&
R&
R
ライブラリ
ヘッダ
の一覧を
表
(
に示す。
表
(
ヘッダ
の一覧
種別
名前
値
7;6E
"<
<A
@65
?BA:
@<A
F7;6E
@<A
G7;6E
@65
GF;E
@65
7;6E
@65
<A
@<A
@"
?8A
@65
F;E
@65
G<A
@65
7;6E
@<A
?BA:
@65
F7;6E
@65
F;E
@<A
G?BA:
@65
このヘッダの内容は,標準
"
ライブラリのヘッダ
(
と同じとする。
ヘッダ
の一覧を
表
)
に示す。
表
)
ヘッダ
の一覧
種別
名前
値
#"?
#<:
#"?
@<A
85C
9?
@<A
L.
85C
?#"?
@65
L.
85C
#"?
8CF<?BA
9?
#<:
9?
@<A
85C
?#"?
@65
85C
#"?
@6A
#<:
9?
8CF<?BA
9?
E6#<5
?#"?
@<A
#"?
@65
9?
@6A
#<:
9?
EBGA#F
?#"?
@<A
L.
85C
#"?
@65
L.
85C
9?
@65
?#"?
#<:
?#"?
@<A
85C
#"?
@65
85C
9?
@65
L.
85C
?#"?
8CF<?BA
#"?
@<A
9?
@65
85C
?#"?
@6A
#<:
#"?
@<A
L.
85C
9?
@<A
?#"?
@65
このヘッダの内容は,標準
"
ライブラリのヘッダ
(
と同じとする。
6
の
)#
,
#
及び
#
参照。
開始 及び 終了
ヘッダ
の一部を
表
に示す。
表
ヘッダ
の( 一部の)一覧
種別
名前
マクロ
85<
96<?GE8
85<
FG778FF
関数
は,標準
"
ライブラリの
(
と同じとする。ただし ,この箇条に示す変更がある。
!
関数
の動作規定として,次が追加されている。
―
プログラムは,次の動作を行わずに終了する(
(
参照)
。
―
自動記憶域期間 及び 静的記憶域期間のオブジェクトのデストラクタの実行。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(
―
に渡された関数の呼出し 。
"#"
!
$ !
"#%%"
!
$ !
効果
関数
は,
が指している関数を,正常終了時に実引数なしで呼び出す関数として登録する。
によって登録された関数の実行時に例外が送出され,その関数がその例外に対応するハンド ラをもたな
い場合,
(
(
)が呼び出される。
処理系限界
処理系は,少なくとも
個の関数の登録を保証しなければならない。
返却値
登録に成功した場合はゼロ,失敗した場合はゼロ以外の値を返す。
関数
には次の動作が追加されている。
―
最初に,静的記憶域期間のオブジェクトを解体し ,
で登録した関数を呼び出す。静的記憶域期
間の非局所オブジェクトの解体は,コンストラクタが終了した順序と逆の順序で行われる(
の呼
出しで,自動記憶域期間のオブジェクトが解体されることはない
。)
。
で登録した関数は,
登録と逆の順序で呼ばれる
。ただし ,関数を登録したときに,それよりも前に登録した関数が既に
呼び出されている場合,それらより後に呼び出される。静的記憶域期間の非局所オブジェクト
L
が初
期化される前に
で登録した関数は,
L
の解体が終了するまで呼び出されない。静的記憶域期
間の非局所オブジェクト
+
が初期化された後に
で登録した関数は,
+
の解体が開始され
る前に呼び出される。局所静的オブジェクト
*
は,
*
のデストラクタを呼び出す関数を,
*
の
コンストラクタの完了時に
で登録した場合,同時に解体される。
―
次に,開いている
"
ストリーム(
で宣言されている関数呼出し情報による)が書き出されてい
ないデータをバッファにもつ場合,それらはすべて,フラッシュされる。そして,開いている
"
ストリー
ムがすべて閉じられる。
によって生成したすべてのファイルは,削除される
。
―
最後に,制御がホスト環境に戻る。
がゼロか
85<
FG778FF
である場合,処理系定義の書式の正常
終了を表す状態が返る。
が
85<
96<?GE8
である場合,処理系定義の書式の非正常終了を表す状態
が返る。それ以外の場合は,処理系定義の値が返る
。
関数
を呼び出した側に,制御が戻ることはない(
(
,
(
及び
6
の
)
参照)
。
動的記憶域管理
ヘッダ
は,動的記憶域割付けを管理するための幾つかの関数を定義し ,記憶域管理に
おけるエラーを報告するための要素を定義している。
ヘッダ
の一覧を示す。
Q
P&
P
QR&
P
&
!P &
P
PP
P
P
&
R
!
33$P
$
33P
&
!
33$P
$
33P0
&
!
&
!
33P0
&
!
ST33$P
$
33P
&
!
ST33$P
$
33P0
&
ST!
&
ST!
33P0
&
!
33$P
$
!
&
!
ST33$P
$
!
&
注
自動記憶域期間のオブジェクトは,関数
が自動オブジェクトを含まず,
(
を呼び出すプログラムでは,すべて解体され
る。
で補そくされる例外の送出によって,そういう
に制御を直接移すことができる。
注
関数は,登録ごとに呼び出される。
注
,
$
など(
)のオブジェクトに結び付いているすべての
ストリームは,この前の段階で静的記憶域期間のオブジェクト
が解体されたときに,フラッシュされ,閉じられている。関数
%
は,
&
で宣言されている。
注
マクロ
*#
2I77*22
及び
*#
5">IE*
は,
&.
に定義されている。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(*
!
!
&
ST!
!
&
参照
)
,
)
,
#
,
##
,
#
及び
記憶域の割付け 及び 解放
特に規定してある場合を除き,
)
の規定は,ライブラリの
及
び
にも適用される。
単一オブジェクト 形式
!$
&&'
'
&&
効果
<
式(
#
)によって呼び出される割付け関数(
)
)であって,適切に境界調整された
$
バイト
の大きさの記憶域を割り付ける。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
必須動作
適切に境界調整された記憶域(
)
)に対する空でないポインタを返すか,又は 例外
を送出
する。この関数を置換した関数も,この要求を満足しなければならない。
既定の動作
―
ループを実行する。そのループ内で,要求された記憶域を割り付けようと試みる。このとき,標準
"
ライ
ブラリの
を呼び出すか否かは規定しない。
―
割付けが 成功し た場合,割り付けられた記憶域を指すポ インタを返す。割付けが 成功し なかった場合,
の最後の実引数が空ポインタだったときは,
を送出する。
―
そうでない場合,現在の
(
)を呼び出す。呼び出した関数から戻った後は,ループ
の実行を継続する。
―
ループは,要求した記憶域の確保に成功するか,又は 呼び出した関数
から戻らなかった場
合に終了する。
!$
&&'
'(
&&)
効果
第
段落の
と同じとする。ただし,この関数は,割付けエラーの通知として,例外
を送出する
のではなく,空ポインタを返すと指定した位置指定形式の
<
式によって呼び出される。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
必須動作
適切に境界調整された記憶域(
)
)を指す空でないポインタ 又は 空ポインタを返す。この例外を送出
しない
は,通常の
によって得られるポインタと同じポインタを返す。この関数を置換
した関数も,この要求を満足しなければならない。
既定の動作
―
ループを実行する。そのループ内で,要求された記憶域を割り付けようと試みる。このとき,標準
"
ライ
ブラリの
を呼び出すか否かは規定しない。
―
割付けが 成功し た場合,割り付けられた記憶域を指すポ インタを返す。割付けが 成功し なかった場合,
の最後の実引数が空ポインタだったときは,空ポインタを返す。
―
そうでない場合,現在の
(
)を呼び出す。呼び出した関数から戻った後は,ループ
の実行を継続する。
―
ループは,要求された記憶域の確保に成功するか,又は 呼び出した関数
から戻らなかった場
合に終了する。呼び出した関数
が
を送出して終了した場合,空ポインタを返す。
例
!
L
%
&
''
失敗した場合,
P
を送出する。
!
+
%
&
''
失敗した場合,
.
を返す。
!
!$
!
!$
(
&&)
効果
3
式によって呼び出される解放関数(
)
)であって,
の値を無効にする。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
必須動作
の値として,次の値を受け付けなければならない。
―
空ポインタ。
―
既定の
33$
が返した値。
―
既定の
33$
33
0
が返した値。
既定の動作
―
が空ポインタの場合,何も行わない。
―
空ポインタでない場合,
の値は,既定の
によってそれ以前に返され ,かつ
!
によって無効化されていない値でなければならない(
))
参照)
。そういう空でない
ポインタの場合,既定の
によって割り付けられた記憶域を解放する。
参考
解放された記憶域が,
又は
で宣言された
,
若しくは
のいずれかによって再利用される条件は規定しない。
配列形式
!$
*+ &&'
'
&&
効果
配列形式の《
<
式》
(
#
)によって呼び出される割付け関数(
)
)であって,適切に境界調整された
$
バイトの大きさの記憶域を割り付ける
。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
必須動作
33$
と同じとする。この関数を置換した関数も,この要求を満足しなければな
らない。
既定の動作
$
の結果を返す。
!$
*+ &&'
'(
&&)
効果
第
段落の
と同じとする。ただし,この関数は,割付けエラーの通知として,例外
を送出する
のではなく,空ポインタを返すと指定した位置指定形式の
<
式によって呼び出される。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
必須動作
33$
33
0
と同じとする。この例外を送出しない
は,通常の
によって得られるポインタと同じポインタを返す。この関数を置換した関数も,この
要求を満足しなければならない。
既定の動作
$
の結果を返す。
!
*+ !$
!
*+ !$
(
&&)
効果
配列形式の
3
式によって呼び出される解放関数(
)
)であって,
の値を無効にする。
置換可能性
"##
プログラムは,この関数と同じ呼出し情報をもつ関数を定義して,標準
"##
ライブラリで定義
されている版を置換することができる。
必須動作
の値として,次の値を受け付けなければならない。
―
空ポインタ。
―
既定の
ST33$
が返した値。
―
既定の
ST33$
33
0
が返した値。
既定の動作
―
が空ポインタの場合,何も行わない。
―
空ポインタでない場合,
の値は,それ以前に,既定の
33$
によって返され
た値でなければならない
。そういう空でないポインタの場合,既定の
によって割り
付けられた記憶域を解放する。
解放された記憶域が,
又は
で宣言された
,
若しくは
のいずれ
かによって再利用される条件は規定しない。
注
反復の総数 又は 配列の要素の大きさについては,
&-
又は
&&
の直接の責任
範囲ではない。その操作は,配列の
'
式 及び 配列の
式とは別のどこかで実行される。しかし ,配列の
'
式は,
&-
への実引数
-
の値を増やして,補足の情報を格納する領域を得てもよい。
注
その値は,
&&
(
)の呼出しによって無効化されていてはならない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
位置指定形式
位置指定形式の関数は,予約されている。
"##
プログラムは,これらの関数と同じ呼出し
情報をもつ関数を定義することによって,標準
"##
ライブラリで定義されている版を置換してはならない(
)
参照)。
)
の規定は,これらの予約済みの位置指定形式の
及び
には適用され
ない。
!$
&&'
'(
!$
返却値
。
参考
の値を返す以外の動作は行わない。
例
この関数は,既知のアドレスにオブジェクトを生成するのに有益である。
!
%
$F
&
F!
%
F &
!$
*+ &&'
'(
!$
返却値
。
参考
の値を返す以外の動作は行わない。
!
!$
(
!$
効果
何も行わない。
参考
ライブラリの非配列形式位置指定演算子
を呼び出す位置指定
<
式が,その初期化部分で例外を送
出することによって終了した場合,この関数が既定の関数として呼び出される。
!
*+ !$
(
!$
効果
何も行わない。
参考
ライブラリの配列形式位置指定演算子
を呼び出す位置指定
<
式が,その初期化部分で,例外を送
出することによって終了した場合,この関数が既定の関数として呼び出される。
記憶域割付けエラー
クラス
Q
P
3
Q
3
P
&
P
P0
&
P0
%
P0
&
XP
&
!
&
R&
R
クラス
は,記憶域割付けが失敗したときに処理系が例外として送出するオブジェクトの型を定義する。
効果
クラス
のオブジェクトを生成する。
参考
新たに生成されたオブジェクトに対して
を呼び出した結果は,処理系定義とする。
)
)
,
)
効果
クラス
のオブジェクトをコピーする。
!
$
返却値
処理系定義の
)+4/
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
型
!
$
又は
ST
が新たな記憶域割付けの要求を満足できなかった場合に呼び出される,
ハンド ラ関数の型を表す。
必須動作
は,次のいずれかの動作を行う。
―
より多くの記憶域を割付け可能にしてから戻る。
―
型 又は
の派生クラス型の例外を送出する。
―
又は
を呼び出す。
効果
が指す関数を,新たな
とする。
返却値
最初の呼出しでは
を返す。以後の呼出しでは,直前の
の値を返す。
#
型の識別
ヘッダ
は,処理系によって生成される型情報に関連する型,及び 動的な型識別エラー
を報告するための二つの型を定義する。
Q
P&
P&
P&
R
#)
及び
#
参照。
#
クラス
Q
P
Q
3
XP &
%%
P0
&
[%
P0
&
P0
&
!
&
3
P
P0
&
P0
%
P0
&
R&
R
クラス
は,処理系が生成する型情報を表す。このクラスのオブジェクトは,型名へのポインタを効率よ
く格納し ,二つの型の同等性 又は 順序を比較するのに適した符号化された値を効率よく格納する。名前,符号化の
規則 及び 型の順序は,規定しない。これらは,プログラムによって異なっていてもよい。
,,
)
効果
現在のオブジェクトを
と比較する。
返却値
二つの値が同じ型を表すとき,
とする。
-,
)
返却値
[!
%%
。
)
効果
現在のオブジェクトを
と比較する。
返却値
処理系が定める順序に基づいて,
!
が
より前にあるとき,
とする。
$
返却値
処理系定義の
)+4/
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
参考
に変換可能であって,
として表示可能な(
及び
#
参照)ナル文字で終端
した多バイト文字列(
)
)であってもよい。
)
)
,
)
効果
クラス
のオブジェクトをコピーする。
参考
コピーコンストラクタ 及び 代入演算子は,非公開なので,この型のオブジェクトをコピーすることは
できない。
#
クラス
Q
P
3
Q
3
P
&
P
P0
&
P0
%
P0
&
XP
&
!
&
R&
R
クラス
は,正しくない動的キャスト式(
#)
)を実行したとき,処理系が例外として送出するオブジェ
クトの型を定義する。
効果
クラス
のオブジェクトを生成する。
参考
新たに生成されたオブジェクトに対して
を呼び出した結果は,処理系定義とする。
)
)
,
)
効果
クラス
のオブジェクトをコピーする。
!
$
返却値
処理系定義の
)+4/
。
参考
に変換可能であって,
として表示可能な(
及び
#
参照)ナル文字で終端
した多バイト文字列(
)
)であってもよい。
#
クラス
Q
P
3
Q
3
P
&
P
P0
&
P0
%
P0
&
XP
&
!
&
R&
R
クラス
は,
1
3
式(
#
)中に空ポインタが含まれる場合に,処理系が例外として送出するオブ
ジェクトの型を定義する。
効果
クラス
のオブジェクトを生成する。
参考
新たに生成されたオブジェクトに対して
を呼び出した結果は,処理系定義とする。
)
)
,
)
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
効果
クラス
のオブジェクトをコピーする。
!
$
返却値
処理系定義の
)+4/
。
参考
に変換可能であって,
として表示可能な(
及び
#
参照)ナル文字で終端
した多バイト文字列(
)
)であってもよい。
(
例外処理
ヘッダ
は,
"##
プログラムにおける例外処理に関する型 及び 関数を定義している。
ヘッダ
の一覧を示す。
Q
&
P&
!P
&
P
P
P
&
&
!P
&
P
P
P
&
&
P
&
R
##
参照。
(
クラス
Q
Q
3
&
0
&
0
%
0
&
X
&
!
&
R&
R
クラス
は,プログラム実行時にエラーが検出された場合に,標準
"##
ライブラリの構成要素 及び あ
る種の式から,例外として送出される型の基底クラスを定義する。
効果
クラス
のオブジェクトを生成する。
参考
いかなる例外も送出しない。
)
)
,
)
効果
クラス
のオブジェクトをコピーする。
参考
代入の後で
を呼び出した結果は,処理系定義とする。
!
.
効果
クラス
のオブジェクトを解体する。
参考
いかなる例外も送出しない。
!
$
返却値
処理系定義の
)+4/
。
参考
に変換可能であって,
として表示可能な(
及び
#
参照)ナル文字で終端
した多バイト文字列(
)
)であってもよい。返却値は,それが確保された例外オブジェクトが
解体されるまで,又は 例外オブジェクトの非定値のメンバ関数が呼び出されるまで,正当とする。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)#
(
例外指定に対する違反
(
クラス
Q
P
3
Q
3
P
&
P
P0
&
P0
%
P0
&
XP
&
!
&
R&
R
クラス
は,例外指定をもつ関数が,指定されていない例外を送出した場合に送出する型(
##
)
を定義する。
効果
クラス
のオブジェクトを生成する。
参考
新たに生成されたオブジェクトに対して
を呼び出した結果は,処理系定義とする。
)
)
,
)
効果
クラス
のオブジェクトをコピーする。
!
$
返却値
処理系定義の
)+4/
。
参考
に変換可能であって,
として表示可能な(
及び
#
参照)ナル文字で終端
した多バイト文字列(
)
)であってもよい。返却値は,例外オブジェクトが解体されるか 又は
例外オブジェクトの非定値メンバ関数が呼び出されるまで,有効である。
(
型
!
$
関数が例外指定に書かれていない例外を送出しようとした場合,
によって呼び出されるハンド ラ関
数の型を表す。
必須動作
は,戻ってはならない(
##
参照)
。
既定の動作
処理系の既定の
は,
を呼ぶ。
(
効果
が指す関数を,新たな
とする。
条件
は空ポインタであってはならない。
返却値
直前の
の値。
(
!
関数が,例外指定に書かれていない例外によって終了しようとしたとき,処理系から呼び出される(
##
参照)
。
プログラムから直接呼ぶこともできる。
効果
動作は次のとおりとする。
―
処理系から呼び出された場合,
<
式(
(
)を評価した直後に
を呼ぶ。
―
プログラムから呼び出された場合,その時点の
を呼ぶ。
(
異常終了
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)(
(
型
!
$
例外処理を強制終了する場合に,
から呼び出されるハンド ラ関数の型を表す。
必須動作
は,呼出し側に戻ることなく,プログラムの実行を終了させなければならない。
既定の動作
処理系の既定の
は,
を呼ぶ。
(
効果
が指す関数を,例外処理を終了するための新たなハンド ラ関数とする。
条件
は空ポインタであってはならない。
返却値
直前の
の値。
(
!
なんらかの理由で,例外処理を中止しなければならない場合に,処理系によって呼び出される関数を表す(
##
参照)
。プログラムから直接呼ぶこともできる。
効果
動作は次のとおりとする。
―
処理系から呼び出された場合,
<
式(
(
)を評価した直後に,
を呼ぶ。
―
プログラムから呼び出された場合,その時点の
を呼ぶ。
(
返却値
次のいずれかの期間にある間は,
とする。
―
<
式の評価が完了してから,合致するハンド ラの例外宣言の初期化が終了するまで 又は その送出の
結果として
に入るまで。
―
に入った後。明示的に呼び出した場合を除く。
参考
この期間は,スタックの巻戻し(
#
)を含む。
参考
が
である間に例外を送出すると,
(
##
)が呼び出される。
)
他の実行時支援
ヘッダ
(可変実引数),
(通常の飛越し ),
(システムの時刻
及び
),
(シグナル操作) 並びに
( 実行時環境
及び
)
を示す。
表
*
ヘッダ
の一覧
種別
名前
マクロ
型
表
ヘッダ
の一覧
種別
名前
マクロ
型
関数
表
ヘッダ
の一覧
種別
名前
マクロ
7?B7>F
C8E
F87
型
関数
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
))
表
ヘッダ
の一覧
種別
名前
マクロ
F<:6"E
F<:<??
F<:F8:H
F<:
#9?
F<:
<:A
F<:9C8
F<:<A
F<:8E@
F<:
8EE
型
関数
表
ヘッダ
の一覧
種別
名前
関数
,
,
,
,
は ,それぞれ 標準
"
ライブ ラリの
(
,
(
,
(
,
(
,
(
と同じとする。ただし,次の変更がある。
(
中のマクロ
の第
仮引数に対する制限は,
6
と異なる。この規格では,仮引
数 最終仮引数 に対応する仮引数は,関数定義中の可変個数の仮引数並びの中で最右端にある識別子(
(((
の直前にあ
るもの )とする。更に,最終仮引数 が次のいずれかの型の場合,その動作は未定義とする(
6
の
参照)
。
―
関数型
―
配列型
―
参照型
―
対応する仮引数が宣言されていない実引数の場合に起こる,型変換後の型と適合しない型
この規格での関数
の動作は,次のとおり,より制限されている。ある場所で
例外が送出され制御がプログラムの別の場所( 飛び先)に移り,そこで自動オブジェクトが解体されるとする。その例
外送出と同じ場所で,同じ飛び先に制御を移す
を呼び出した場合,その動作は未定義とする。
6
の
)
,
)
,
)(
及び
)
参照。
"
と
"##
の共通部分集合は,適格な
"##
プログラム 及び 適格な
"
プログラムの両方に現れることのできる宣
言,定義,式から構成される。
"
互換関数
2O
1
3
とは,共通部分集合の機能だけを使用した関数
であって,直接にも間接にも
"
互換関数以外の関数を使用しないものとする。すべてのシグナル処理ルーチンは,
"
結合をもたなければならない。
"
標準に適合する
"
プログラムでシグナル処理ルーチンとして使うことのできる
"
互換関数は,
"##
プログラムでシグナル処理ルーチンとして使った場合に動作が未定義となってはならない。
"##
プログラムのシグナル処理ルーチンとして他の関数を使った場合の動作は,処理系定義とする
。
*
診断ライブラリ
この箇条では,
"##
プログラムがエラーを検出して報告するために利用できるライブラリ
要素を規定する。
*
〜
*
では,
表
にあるように,ある種の例外条件の報告,プログラム表明の記録 及び エラー番号用の大
域的変数として利用する要素について規定する。
表
診断ライブラリの要約
箇条
ヘッダ
*
例外クラス
*
表明
*
エラー番号
*
例外クラス
標準
"##
ライブラリは,
"##
プログラムにおけるある種のエラー(
)
)を報告するの
に使われるクラスを提供する。これらのクラスに反映されるエラーは,論理エラー 及び 実行時エラーの二つに大別
される。
論理エラーの特徴は,プログラムの内部的論理によって引き起こされる点にある。理論的には,論理エラーは回避
可能である。
注
特に,例外ハンド ラを用いるシグナル処理ルーチンは,問題を起こすことが多い。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)
これに対し,実行時エラーは,プログラムの範囲外の事象によって引き起こされる。このようなエラーを事前に予
測することは難しい。ヘッダ
は,
"##
プログラムにおいてエラーを報告するのに使われる幾つかの型
を定義している。これらの例外は,継承によって関連付けられている。
ヘッダ
一覧
Q
P&
P&
P
&
P&
PP&
P&
P&
P&
P&
R
*
クラス
Q
P
3
Q
3
P
0
P &
R&
R
クラス
は,プログラム実行前に検出可能であるようなエラー( 例えば ,論理的な事前条件 又は クラ
ス不変式に対する違反など )を報告するのに送出する例外オブジェクトの型を定義する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
*
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,ド メイン エラーを報告するのに送出する例外オブジェクトの型を定義する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
*
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,不正な実引数を報告するのに送出する例外オブジェクトの型を定義する。
!
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
)*
*
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,最大長を越えた長さのオブジェクトを生成しようとしたことを報告するのに送出する例
外オブジェクトの型を定義する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
*#
クラス
Q
PP
3
P
Q
3
PP
0
P &
R&
R
クラス
は,実引数の値が範囲外であることを報告するのに送出する例外オブジェクトの型を定義する。
)
効果
クラス
クラスのオブジェクトを構築する。
事後条件
(
%%
.
となる。
*(
クラス
Q
P
3
Q
3
P
0
P &
R&
R
クラス
は,プログラムを実行しないと検出できないようなエラーを報告するのに送出する例外オ
ブジェクトの型を定義する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
*)
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,内部計算で発生する範囲エラーを報告するのに送出する例外オブジェクトの型を定義する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
*
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,算術的なオーバフローエラーを報告するのに送出する例外オブジェクトの型を定義する。
!
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
**
クラス
Q
P
3
P
Q
3
P
0
P &
R&
R
クラス
は,算術的なアンダフローエラーを報告するのに送出する例外オブジェクトの型を定義
する。
)
効果
クラス
のオブジェクトを構築する。
事後条件
(
%%
.
となる。
*
表明
標準
"##
ライブラリは,
"##
プログラムの表明を記録するマクロ 及び 表明の検査を無効化するマク
ロを提供する。
表
#
に,ヘッダ
を示す。
表
#
ヘッダ
一覧
種別
名前
マクロ
ヘッダ
は,標準
"
ライブラリの
(
と同じとする。
参照
6
の
)
。
*
エラー番号
表
(
に,ヘッダ
を示す。
表
(
ヘッダ
一覧
種別
名前
マクロ
8#B@
8E6A:8
ヘッダ
の内容は,標準
"
ライブラリの
(
と同じとする。
参照
6
の
)
及び
)
並びに
6
追補
の
。
一般ユーティリティ ライブラリ
この箇条では,標準
"##
ライブラリの他の部分から利用されるライブラリ
要素を規定する。これらの要素は,
"##
プログラムからも利用することができる。
〜
#
で,ユーティリティ 及び 割付け子の要件,ユーティリティの構成要素,関数オブジェクト,動的メモ
リ管理ユーティリティ,並びに 日付 及び 時刻のユーティリティを規定する(その一覧を
表
)
に示す)
。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
表
)
一般ユーティリティ ライブラリ一覧
箇条
ヘッダ
要件
ユーティリティ構成要素
関数オブジェクト
メモリ
#
日付 及び 時刻
要件
では,テンプレート実引数に対する要件を規定する。
〜
では,テンプレートを具現
するのに用いる型に対する要件を規定する。
#
では,記憶域割付け子に対する要件を規定する。
等価性比較
表
において,
はテンプレートを具現するのに用いる型とし ,
,
及び
は型
の値と
する。
表
等価性比較可能な型
87
の要件
式
返却値の型
要件
%%
に変換
%%
は,等価関係の一つであり,次の条件を
可能な型
すべて満足しなければならない。
―
すべての
について,
%%
となる。
―
%%
ならば ,
%%
となる。
―
%%
かつ
%%
ならば ,
%%
。
小なり比較
表
*
において,
はテンプレートを具現するのに用いる型とし ,
,
及び
は型
の値と
する。
表
*
小なり比較可能な型
?7
の要件
式
返却値の型
要件
に変換可能な型
は,純弱順序関係とする(
#
参照)
。
コピー構築
表
において,
はテンプレートを具現するのに用いる型とし,
は型
の値,
は型
の値とする。
表
コピー構築可能な型
77
の要件
式
返却値の型
要件
は,
と等価とする。
は,
と等価とする。
(X
0
!
のアドレスを表す。
0
!
のアドレスを表す。
省略時コンスト ラクタ
省略時コンストラクタは,必須ではない。ある種のコンテナクラスのメンバ関数の
呼出し情報が,省略時実引数として省略時コンストラクタを指定していることがある。そのような呼出し情報が省略
時実引数(
(
)を用いて呼ばれる場合,
は,適切に定義された式でなければならない(
#
参照)
。
#
割付け子に対する要件
標準ライブラリは,割付け子に対する標準的な要件を規定している。ここで,割付
け子とは,記憶域割付けモデルに関する情報をカプセル化するためのオブジェクトとする。記憶域割付けモデルに関
する情報には,ポインタ型,ポインタの差分を表す型,この割付けモデルにおけるオブジェクトのサイズを表す型,
メモリの割付け 及び 解放の基本処理
10
などが含まれる。すべてのコンテナ(
)は,割付け子をテンプ
レート仮引数にもつ。
表
に,割付け子が操作する型に対する要件を規定する。割付け子に対するすべての操作は,一定の時間で完了
する。
表
に,割付け子の型に対する要件を規定する。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
表
説明に用いる変数の定義
変数
定義
,
G
任意の型
5
型
の割付け子のクラス
J
型
G
の割付け子のクラス
型
0
の値
,
L,
+
型
50
の値
型
J
の値
L(
を呼び出して得られる 型
533
の値。ここで,
L
%%
とする。
値
を変換して得られる 型
533
の値。
式
!
によって得られる 型
533
の値。
式
!
によって 又は
を変換して得られる
型
533
の値。
J33
を呼び出して得られる
型
J33
の値 又は
。
型
533$
の値。
表
割付け子に対する要件
式
返却値の型
説明
事前条件
事後条件
533
へのポインタ
533
へのポインタ
533
0
533
0
533
と同等。
533$
符号なし整数型
注意
その割付けモデルで最大のオブジェクト
のサイズを表すことができる型でなければならない。
533
符号付き整数型
注意
その割付けモデルにおける任意のポインタ間
の差分を表すことができる型でなければならない。
533
J
条件
すべての
G
(
を含む。)に対し ,
G33
J33
33
は,
5
となる。
(
533
(
533
(
533
条件
個の
型オブジェクトのためのメモリが割り
(
付けられる。ただし ,オブジェクトは構築されない。
が,例外を送出することもある。結果は,
ランダムアクセス反復子とする。
参考
%%
.
の場合,返却値は未規定とする。
(
( 使われない。)
条件
の指す位置にある
個の型
の
オブジェクトは,この呼出しの前に解体されていな
ければならない。
は,この記憶域を割り付ける
ときに
に渡された値と一致していなけ
ればならない。例外を送出することはない。
参考
は,空であってはならない。
(
$
533$
効果
533
に渡すことができる最大の値。
L
%%
+
効果
一方で割り当てられた領域が,他方を介して解放
可能な場合に限り
を返す。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
表
割付け子に対する要件( 続き)
式
返却値の型
説明
事前条件
事後条件
L
[%
+
効果
[L
%%
+
に等しい。
5
効果
省略時のインスタンスを生成する。
参考
デストラクタの存在は仮定されている。
5
事後条件
J
%%
となる。
(
( 使われない。)
効果
!
を呼び出す。
(
( 使われない。)
効果
! VX
を呼び出す。
上の表内の メンバ クラステンプレ ート
は,実質的には型定義テンプレ ートとなる。割付け子の名前が
F6
に結合している場合,
633
G
33
は,
F6G
と同じ型となる。
処理系は,この規格で規定しているコンテナを実装するに当り,割付け子のテンプレート仮引数が,
表
の要件
に加え,次の二つの要件も満足しているものとしてよい。
―
割付け子の型のすべてのインスタンスは交換可能である必要があり,互いに等価かど うかを比較できなけ
ればならない。
―
型定義の メンバ,
,
,
$
及び
は,それぞれ ,
!
,
!
,
$
及び
としなければならない。
処理系は,より一般的な記憶域モデルをカプセル化し,等価でないインスタンスを許すような割付け子を受け付け
るライブラリを提供することが望ましい。そのような処理系では,コンテナによって割付け子に課せられる要件が
表
にある要件を超えてもよい。その場合,コンテナの意味規則 及び 割付け子のインスタンスが等価でない比較がで
きるアルゴ リズムは,処理系定義とする。
ユーティリティ構成要素
では,標準ライブラリの他の部分で利用される基本的な関数テンプレート 及
び クラステンプレートを規定する。
ヘッダ
一覧
Q
''
+.(+(L
演算子
P
Q
[%
0
0 &
0
0 &
%
0
0 &
%
0
0 &
R
''
+.(+(+
対
つい
L
+
&
L
+
%%
L +0
L +0 &
L
+
L +0
L +0 &
L
+
[%
L +0
L +0 &
L
+
L +0
L +0 &
L
+
%
L +0
L +0 &
L
+
%
L +0
L +0 &
L
+
L +
PL
+ &
R
演算子
演算子
%%
とは別に演算子
[%
を定義すること,並びに 演算子
とは別に演算子
,
%
及び
%
を
定義することは,冗長な定義となるので,標準ライブラリは,次のテンプレートを提供している。
/
0
-,
)
(
)
注
-%
が小さい場合でも,
0
が,型
のオブジェクトを一つ割り付ける有効な方法となることを意図している。すな
わち,コンテナがそれ自身の
空き領域リスト
を管理する必要はない。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
要件
型
は,
で規定した意味で等価性の比較ができなければならない。
返却値
[
%%
/
0
0
)
(
)
要件
型
は,
の意味で,演算子
によって大きさの比較ができなければならない。
返却値
/
0
/,
)
(
)
要件
型
は,
の意味で,演算子
によって大きさの比較ができなければならない。
返却値
[
/
0
0,
)
(
)
要件
型
は,
の意味で,演算子
によって大きさの比較ができなければならない。
返却値
[
このライブラリ内では,
[%
,
,
%
又は
%
という演算子が宣言されているが,その要件 及び 意味規則が明示的
に書かれていない場合,その要件 及び 意味規則は,この箇条での規定に従う。
対
このライブラリは,種類の異なる
個の要素から成る対
つい
1
のテンプレートを提供している。
また,対の構築を容易にするための関数テンプレートも提供している。
L
+
Q
L
P&
+
P&
L
&
+
&
&
L0
+0
&
G
H
G
H
0 &
R&
効果
コンストラクタは,次のように実装されているものとしてメンバを初期化する。
3
L
+
QR
)
(
1)
効果
コンストラクタは,
を
で,
を
で初期化する。
/
2(
30
/2(
30
)
効果
各メンバを,対応する実引数のメンバで初期化する。必要ならば暗黙の型変換を行う。
/
(
10
,,
/(
10)
(
/(
10)
返却値
(
%%
(
00
(
%%
(
/
(
10
/
/(
10)
(
/(
10)
返却値
(
(
11
[(
(
00
(
(
/
(
10
/(
10
4
(
1
返却値
L
+
。
注
によって,処理系は,必須ではないコピーをしないために,実引数のコピーを行わなくてもよい。
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#
例
/
*(LML/O+- &
''
明示的な型
こう書く場所で,
"##
プログラムでは,次のように書いてもよい。
P/
*(LML/O+- &
''
型が導出される。
関数オブジェクト
関数オブジェクト
%
=
とは,
が定義されているオブジェクトを
いう。関数オブジェクトは,標準ライブラリを効果的に利用するのに重要な役割を果す。アルゴ リズム テンプレート
(
#
)に関数へのポインタを渡すことができるところでは,
が定義されているオブジェクトを渡すこと
ができるようにインタフェースが規定されている。これによって,アルゴ リズム テンプレートは,関数へのポインタ
を受け付けることができ,任意の関数オブジェクトを受け付けることもできる。
ヘッダ
一覧
Q
''
+.(*(L
基本
6
E
P&
6L
6+
E
P&
''
+.(*(+
算術演算
&
&
&
&
&
&
''
+.(*(*
比較演算
P&
PP&
&
&
P&
P&
''
+.(*(M
論理演算
P&
P&
P&
''
+.(*(/
否定子
C
P&
C
PC
L
C0 &
C
P&
C
PC
+
C0 &
''
+.(*(-
結合子
B
L&
B
LB
L
B0
0 &
B
+&
B
+B
+
B0
0 &
''
+.(*(,
アダプタ
6
E
PP
P
&
6
E
PPP
6
E
PE
! 6 &
6L
6+
E
PP
P
&
6L
6+
E
PP
P
6
L
6
+
E
PE
! 6L 6+ &
2019
年
7
月
1
日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。