tag:blogger.com,1999:blog-3636872937372639901.post4704556818601688324..comments2024-03-27T21:24:43.584+09:00Comments on 本の虫: constexprがわけわからないレベルに達している江添亮http://www.blogger.com/profile/13387122818743087721noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-3636872937372639901.post-80981924881487328032010-09-19T20:34:08.620+09:002010-09-19T20:34:08.620+09:00非constexpr関数のポインターは、定数式ではないので、そもそも初期化に失敗します。非constexpr関数のポインターは、定数式ではないので、そもそも初期化に失敗します。江添亮https://www.blogger.com/profile/13387122818743087721noreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-22243579032265164992010-09-19T19:22:21.853+09:002010-09-19T19:22:21.853+09:00なるほど。 constexpr なテーブルから取り出した
関数ポインタであれば、それを経由して呼び出...なるほど。 constexpr なテーブルから取り出した<br />関数ポインタであれば、それを経由して呼び出す関数も<br />constexpr なものかどうか、型によらず判別可能という<br />ことですね。<br /><br />table[] に constexpr でない関数へのポインタが<br />混ざっていた場合は、与えるインデックスによっては<br />コンパイルエラーになる、と。<br /><br />理解しました。コンパイラ実装者はたいへんになりそう<br />ですね。Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-84101169074410324862010-09-15T13:04:25.423+09:002010-09-15T13:04:25.423+09:00関数呼び出し式のオペランドが、lvalueの関数、ポインター、リファレンス、いずれでも、それは「関数...関数呼び出し式のオペランドが、lvalueの関数、ポインター、リファレンス、いずれでも、それは「関数を呼び出す」といえます。<br /><br />5.19/2には、定数式となる場合を列挙してありますが、constexprな関数の呼び出しは、引数も定数式などの条件を満たせば、定数式であると書いてあります。どのように呼び出すものが該当するのかということは書いてありません。<br />つまり、どんな呼び出しであろうと、constexpr関数を参照する定数式のオペランドに対して、定数式の条件を満たして、関数呼び出しの演算子を適用した場合、定数式になります。<br /><br />そのため、ポインター経由のconstexpr関数の呼び出しも、定数式になりえます。<br />関数ポインターも定数式であればいいのです。<br /><br />これは、標準化委員会でも合意が取れている解釈です。江添亮https://www.blogger.com/profile/13387122818743087721noreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-10557707355652647652010-09-15T11:32:57.123+09:002010-09-15T11:32:57.123+09:00constexpr が type specifier であるとは言っているわけではありません。
(む...constexpr が type specifier であるとは言っているわけではありません。<br />(むしろ逆のことを言っているつもりです。)<br /><br />constexpr は型に影響しないことにより、関数に対する constexpr 修飾が<br />不可能となる関数ポインタ経由の関数呼び出しは constexpr function に<br />含めることはできない、という指摘をしています。<br /><br />constexpr int (*table[])(void) における constexpr は table の宣言に<br />影響するのであって、それが自動的にポインタの指す先に波及したりは<br />しません。 static int (*table[])(void) としても table が static になる<br />だけで、ポインタの指す関数に static が波及するわけではないのと同様です。<br /><br />関数が constexpr function となる( constexpr function から呼び出せる<br />関数となる)条件は 7.1.5 p2 にしか見当たりません。Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-21569770328366206952010-09-15T04:58:55.041+09:002010-09-15T04:58:55.041+09:00constexprはtype specifierではありません。
したがって、constexprは型...constexprはtype specifierではありません。<br />したがって、constexprは型には影響しません。<br />また、関数ポインターはリテラル型です。リテラル型は、constexpr指定できます。<br />定数式では、ポインターを取得するのに、かなりの制限があるというだけです。江添亮https://www.blogger.com/profile/13387122818743087721noreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-67926679237132023332010-09-15T01:52:04.907+09:002010-09-15T01:52:04.907+09:00> 以下のようなことができるはずである。
table[i]() で呼び出している関数は con...> 以下のようなことができるはずである。<br />table[i]() で呼び出している関数は constexpr function ではないので、<br />constexpr function である call() の中からは呼び出せません。<br />少なくとも現行のドラフトでは「 constexpr function へのポインタ」という<br />型は存在しません。Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3636872937372639901.post-91737972795837728242010-09-14T23:22:15.930+09:002010-09-14T23:22:15.930+09:00Bjarne Stroustrupが恐れていた混沌の領域に達していませんか・・・
確かにやってやれ...Bjarne Stroustrupが恐れていた混沌の領域に達していませんか・・・<br /><br />確かにやってやれない事はないけどアホみたいに巨大な言語仕様になりますね。萌ゑnoreply@blogger.com