12

constexprに関する私の古い質問の1つを閲覧しているときに、非常に(IMHO)重要なコメントに出くわしました。基本的にそれは要約すると:(これは合法的なC++11です:()

 constexpr double f(bool b)
 {
 return b? 42:42/(rand()+1); // how pure is rand ;)
 }

私の質問は、これが規格で許可されている理由は何ですか。私は参照透過性の大ファンなので、彼らに正当な理由があることを願っています:)そして私はそれを知りたいです。

ところで、関連するQがありますが、ほとんどのAは純粋なことについても言及していません。あるいは、そうするときに、stdがこれを許可する理由を指定していません。 constexprと純粋関数の関係

4

3 に答える 3

9

標準では、関連する要件は、constexpr機能の要件のメイン リストの下に埋もれています。それは§7.1.5/5にあります:

constexpr 関数の場合、関数呼び出し置換が定数式 (5.19) を生成するような関数引数値が存在しない場合、プログラムは不正な形式です。診断は必要ありません。

§5.19 は、定数式の要件を定義しているため、 を呼び出すことはできませんrand()

制限の緩和により、条件付きで純粋な関数を使用できます。あなたの例f(true)は有効なテンプレート引数ですが、f(false)そうではありません。

もちろん、欠点は、constexpr関数が意図した目的で実際に使用できるかどうかをコンパイラが検証しないことです。テストケースを書く必要があります。

あ、litbさんの回答も正解です。(しかし、これはもっと簡単に表現されています。)

于 2013-01-23T04:03:13.593 に答える
7

関数定義のキーワードは、すべての引数と変数がコンパイル時に既知である場合、この関数コンパイル時に実行される可能性があることconstexprをコンパイラに伝えます。ただし、そのような保証はありません。たとえば、一部の値が実行時にしかわからない場合、その関数は実行時に実行されます。

ただし、純粋または不純とは関係ありません。これらの用語は、出力が入力のみに依存することを意味し、入力パラメーターの同じ値で関数を何度呼び出しても、出力は毎回同じになるためです。コンパイル時または実行時に計算されるかどうかに関係なく。

例、

constexpr int add(int a, int b) { return a + b; } //pure!

const int a = 2, b = 3; //const
int c = 2, d = 3;       //non-const

//we may read update c and d here!

const int v1 = add(2,3);  //computed at compile-time
const int v2 = add(a,3);  //computed at compile-time
const int v3 = add(2,b);  //computed at compile-time
const int v4 = add(a,b);  //computed at compile-time

const int v3 = add(c,3);  //computed at runtime
const int v3 = add(c,b);  //computed at runtime
const int v3 = add(a,d);  //computed at runtime
const int v3 = add(c,d);  //computed at runtime

ここでaddは、コンパイル時または実行時に計算されるかどうかに関係なく、純粋な関数であることに注意してください。

于 2012-11-08T18:18:08.960 に答える
6

入力パラメーターの一部のドメインでは、不純なパスが使用されることはないためです。そのドメインでは、constexpr は正常に機能します。

たとえば、関数には単純な分岐とより複雑な分岐がある場合があります。また、関数を定数式で使用できるようにするには、関数の引数が、これとその条件が満たされ、常に純粋な関数内の単純な分岐に屈するようなものでなければならないことを指定できます。

これの便利な副作用は、一定の計算中にエラーが発生する可能性があることです。つまり、単純な分岐の前提条件に違反すると、不純な式の評価が発生し、コンパイル時エラーが発生する可能性があります (アサーションまたは例外は、ここでは良い考えです。ランタイム コンテキスト)。

于 2012-11-08T19:42:21.187 に答える