188188
189189 < p class ="text-right "> < small >
190190 最終更新日時(UTC):
191- < span itemprop ="datePublished " content ="2025-04-20T14:00:30 ">
192- 2025年04月20日 14時00分30秒
191+ < span itemprop ="datePublished " content ="2025-04-23T03:06:32 ">
192+ 2025年04月23日 03時06分32秒
193193 </ span >
194194 < br />
195195 < span itemprop ="author " itemscope itemtype ="http://schema.org/Person ">
@@ -222,6 +222,22 @@ <h2>概要</h2>
222222< p > これにより、< a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Preconditions。関数呼び出し時に満たされていると関数が想定する条件。満たさなければ未定義の動作。契約属性の`[[expects]]`に相当 "> 事前条件</ a > (preconditions)、< a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当 "> 事後条件</ a > (postconditions)、及びアサーション(assertions)をコード内で明示的に記述できるようになる。</ p >
223223< p > この機能は、関数のインターフェースに対する期待値を明確にする役割があり、バグの早期発見、コードの可読性向上に寄与することが期待されている。</ p >
224224< h2 > 仕様</ h2 >
225+ < h3 > キーワード</ h3 >
226+ < p > < code > pre</ code > 、< code > post</ code > 、< code > assert</ code > は文脈依存キーワードである。これらは< code > override</ code > や< code > final</ code > と同様に、特定の文脈でのみ特別な意味を持つ。</ p >
227+ < ul >
228+ < li > 変数名や関数名として使用可能
229+ < br />
230+ < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> int</ span > < span class ="n "> pre</ span > < span class ="o "> =</ span > < span class ="mi "> 42</ span > < span class ="p "> ;</ span > < span class ="c1 "> // OK: 変数名として使用</ span >
231+ < span class ="kt "> void</ span > < span class ="nf "> post</ span > < span class ="p "> ()</ span > < span class ="p "> {}</ span > < span class ="c1 "> // OK: 関数名として使用</ span >
232+ </ code > </ pre > </ div >
233+ </ li >
234+ < li > 契約指定の文脈でのみ特別な意味を持つ
235+ < br />
236+ < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> void</ span > < span class ="nf "> f</ span > < span class ="p "> ()</ span >
237+ < span class ="n "> pre</ span > < span class ="p "> (</ span > < span class ="nb "> true</ span > < span class ="p "> );</ span > < span class ="c1 "> // ここでは契約指定として機能</ span >
238+ </ code > </ pre > </ div >
239+ </ li >
240+ </ ul >
225241< h3 > 契約の種類</ h3 >
226242< p > 契約には以下の3種類が定められている。</ p >
227243< ul >
@@ -239,6 +255,23 @@ <h4><a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成
239255</ code > </ pre > </ div >
240256
241257ここでは、< code > denominator</ code > が0でないことを< a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Preconditions。関数呼び出し時に満たされていると関数が想定する条件。満たさなければ未定義の動作。契約属性の`[[expects]]`に相当 "> 事前条件</ a > として指定している。</ p >
258+ < p > < a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Preconditions。関数呼び出し時に満たされていると関数が想定する条件。満たさなければ未定義の動作。契約属性の`[[expects]]`に相当 "> 事前条件</ a > では、必ずしも関数のパラメータを使用する必要はない。グローバル状態やクラスのメンバ変数など、呼び出し時点で有効な任意の式を使用できる。</ p >
259+ < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="k "> class</ span > < span class ="nc "> Resource</ span > < span class ="p "> {</ span >
260+ < span class ="k "> private</ span > < span class ="o "> :</ span >
261+ < span class ="kt "> bool</ span > < span class ="n "> is_available</ span > < span class ="o "> =</ span > < span class ="nb "> false</ span > < span class ="p "> ;</ span >
262+ < span class ="k "> public</ span > < span class ="o "> :</ span >
263+ < span class ="kt "> void</ span > < span class ="n "> use</ span > < span class ="p "> ()</ span >
264+ < span class ="n "> pre</ span > < span class ="p "> (</ span > < span class ="n "> is_available</ span > < span class ="p "> )</ span > < span class ="c1 "> // 引数を使用していない事前条件</ span >
265+ < span class ="p "> {</ span >
266+ < span class ="c1 "> // リソースを使用</ span >
267+ < span class ="p "> }</ span >
268+
269+ < span class ="kt "> void</ span > < span class ="n "> activate</ span > < span class ="p "> ()</ span > < span class ="p "> {</ span >
270+ < span class ="n "> is_available</ span > < span class ="o "> =</ span > < span class ="nb "> true</ span > < span class ="p "> ;</ span >
271+ < span class ="p "> }</ span >
272+ < span class ="p "> };</ span >
273+ </ code > </ pre > </ div >
274+ </ p >
242275< h4 > < a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当 "> 事後条件</ a > (post)</ h4 >
243276< p > 関数の実行後に満たされているべき条件を指定する。</ p >
244277< p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> int</ span > < span class ="nf "> increment</ span > < span class ="p "> (</ span > < span class ="kt "> int</ span > < span class ="n "> x</ span > < span class ="p "> )</ span >
@@ -250,6 +283,23 @@ <h4><a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成
250283
251284ここでは、< code > increment</ code > 関数の< a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > が< code > x + 1</ code > であることを< a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当 "> 事後条件</ a > として指定している。</ p >
252285< p > < code > post</ code > では、返り値を< code > r</ code > としてバインドし、条件式内で利用している。ここには、任意の変数名が使用できる。変数は定数(< code > const</ code > )な左辺値参照である。</ p >
286+ < p > < a class ="cpprefjp-defined-word " data-desc ="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当 "> 事後条件</ a > の結果名導入子(result-name-introducer)は省略可能である。特に、< code > void</ code > を返す関数では、< a class ="cpprefjp-defined-word " data-desc ="関数呼び出し式の評価結果となるオブジェクト・値 "> 戻り値</ a > を参照する必要がない場合に省略できる。</ p >
287+ < p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="k "> class</ span > < span class ="nc "> Container</ span > < span class ="p "> {</ span >
288+ < span class ="c1 "> // ...</ span >
289+ < span class ="k "> public</ span > < span class ="o "> :</ span >
290+ < span class ="kt "> void</ span > < span class ="n "> clear</ span > < span class ="p "> ()</ span >
291+ < span class ="n "> post</ span > < span class ="p "> (</ span > < span class ="n "> empty</ span > < span class ="p "> ())</ span > < span class ="c1 "> // 結果名導入子を省略した事後条件</ span >
292+ < span class ="p "> {</ span >
293+ < span class ="c1 "> // コンテナの内容をクリア</ span >
294+ < span class ="p "> }</ span >
295+
296+ < span class ="kt "> bool</ span > < span class ="n "> empty</ span > < span class ="p "> ()</ span > < span class ="k "> const</ span > < span class ="p "> {</ span >
297+ < span class ="c1 "> // コンテナが空かどうかを返す</ span >
298+ < span class ="k "> return</ span > < span class ="nb "> true</ span > < span class ="p "> ;</ span >
299+ < span class ="p "> }</ span >
300+ < span class ="p "> };</ span >
301+ </ code > </ pre > </ div >
302+ </ p >
253303< h4 > アサーション(assert)</ h4 >
254304< p > 関数の実行中に満たされているべき条件を指定する。</ p >
255305< p > < div class ="codehilite "> < pre > < span > </ span > < code > < span class ="kt "> void</ span > < span class ="nf "> return_negative</ span > < span class ="p "> (</ span > < span class ="kt "> int</ span > < span class ="n "> value</ span > < span class ="p "> )</ span >
@@ -302,7 +352,7 @@ <h3>使用上の注意</h3>
302352< ul >
303353< li > 契約式内において副作用を要する式を記述した場合(グローバル変数の変更、< code > volatile</ code > 変数への参照、< code > constexpr</ code > でない関数の呼び出しなど)</ li >
304354< li > 契約式内で< a class ="cpprefjp-defined-word " data-desc ="問題が発生したときに、現在実行位置を過去に通過・記録した位置に戻し、文脈情報を添えて紐づけられた処理(例外ハンドラー)を呼び出す仕組み。またはその事態 "> 例外</ a > を送出すると、std::terminate()が呼び出され、プログラムが終了する。</ li >
305- < li > 通常の関数やメンバ関数には契約を適用できるが、特殊な関数(例えば< code > default</ code > によって定義されたコピーコンストラクタやデストラクタ)には適用できない。適用すると、プログラムは不正 (ill-formed)となる。</ li >
355+ < li > 通常の関数やメンバ関数には契約を適用できるが、特殊な関数(例えば< code > default</ code > によって定義されたコピーコンストラクタやデストラクタ)には適用できない。適用すると、プログラムは < a class =" cpprefjp-defined-word " data-desc =" プログラムが適格でないこと。コンパイルエラーなどになる " href =" ../../implementation-compliance.html#dfn-ill-formed " > 不適格 </ a > (ill-formed)となる。</ li >
306356</ ul >
307357< h2 > < a href ="#relative-page " id ="relative-page "> 関連項目</ a > </ h2 >
308358< ul >
0 commit comments