constexprの中にC ++:
1.決意時および実行時の決意をコンパイル:決意するのconst int型A = 3コンパイル時間、などのconst int型B = funcを決定()を実行している、コンパイル時に決定され、Bは実行時に決定されます。
、一定の値を返すconstexprの関数の戻り値を受信した場合、CONSTによって受信された場合、この時間は、まだ決定されたランタイムで、constexprの、しかしFUNC()関数の実装は、FUNC(){リターン3}である場合INT B =のFUNC();コンパイル時定数でコンパイラは、その特性を決定することができます。
constexprの表示は、この値が一定であるコンパイラに指示します。しかし、関数funcの戻りが一定でない場合、constexprのint型のFUNC(){戻り関数func2();}この時間constexprのは、指定されたが、時定数の値がまだ実行時まで延期することが決定されるが関数func2の変数は、値を返します。
constexprのの役割:定数式のコンパイル・フェーズを確認するために、事前に一定の値情報。
2.constexpr修正ポインタがトップのポインタ、有効なポインタを示しています。
3.C ++仮想ことができない、11は、関数の戻り値を指定し、パラメータがリテラルであることが保証され、唯一のリターンされなければならない;(関数の戻り値; C ++ 14をC ++ 11に対して確保する必要がないだけretuanその戻り値は三オペレータ又は再帰複雑な状況)を用いて計算することができます。
constの式の後、実行時に一定の特性を決定することができ、変更された属性(一定値)コンパイラconstexprの式によって決定される定数:CONSTとconstexprの修正変数がとき。
CONST及び修正機能場合constexprのコンパイラのプロパティ場合constexprの定数関数のパラメータを決定することができない、等価CONST
ときのconstとconstexprの変更されたクラス:コンストラクタはconstのすることはできませんが、クラスのコンストラクタリテラルはconstexprの関数であってもよいが。実際には、リテラル定数constexprのクラスは、少なくとも1つのコンストラクタを提供する必要があります。
constexprの=コンストラクタは既定のフォームとして(または削除機能の形で)を宣言することができます。それ以外の場合は、コンストラクタの両方の要件を満たす必要がありconstexprのコンストラクタ(return文が含まれていないという意味)だけではなく、(それが唯一の実行文を持つreturn文をされることを意味)constexprの機能要件を満たすために。
関数メンバの初期化は、初期化リストに配置されなければならないので、クリアこれら2点をとり、一般にconstexprのコンストラクタ本体は、空でなければなりません。すべてのデータメンバを初期化する必要がありconstexprのコンストラクタは、constexprのコンストラクタは、それに渡されたすべてのパラメータがconstexprの種類、すべてのメンバーはまた、生成されたオブジェクトconstexprのある保証します
参考住所:https://www.jianshu.com/p/34a2a79ea947
https://blog.csdn.net/qq_37653144/article/details/78518071
次のターン: https://www.cnblogs.com/wangxiaobao/p/5966394.html
スコット・マイヤーズ在効果的な近代的なC ++中提到「C ++ 11の中で最も混乱する新しい単語のための賞があった場合は、constexprのは、おそらくそれに勝つでしょう。」
このように、確かに多くの困難constexprのは理解します。一緒にその中にC ++ 11標準および14と若干異なりますが、また、この問題を悪化させます。
古典的な教科書の基準数(C ++プライマー、効果的な近代的なC ++、Cのツアー++) と青大幅にconstexprの使い方や注意事項を整理、平和で回答のいくつかを知っています。
1.コンセプト、constexprのオブジェクト
C ++プライマーの定義は、で与えられる「定数式に変更しないことを意味し、計算結果は、コンパイル式中得ることができる [1]。」
CONST及び資格、すなわち上に塗布層として理解することができるCONSTは、コンパイラの定数または定数の操作に限定されるものではなく、そしてconstexprのは、コンパイル時なければならない(結果をコンパイル時)定数。
たとえば、次のように:
我々はすべて知っているように、サイズの配列は、コンパイル時に決定されるので、そのサイズは定数式でない場合、コンパイル経由ではありません。
私はint型、 CONST INTサイズ= I; INT ARR [サイズ]; //エラー、発現が一定の大きさではないが、コンパイル時に決定することができません
サイズが可変でconstexprのであれば、コンパイラによって決定適格コンパイルです。
自動サイズ= 10 constexprの; int型ARR [サイズ]; // OK、サイズ定数式
あなたは定数式を定義したい場合は、当然、我々はまた、それ以外の場合はそこにコンパイルされません、右側が定数式であることを確認する必要があります。
私はint型、 constexprの=私はサイズをint型; //エラー、コンパイル時に決定することができないI
だから、一つの文章の要約で効果的な近代的なC ++でこの部分です。
「constexprのオブジェクトはconstのであり、コンパイル時に既知の値で初期化されている【2】」。
2. constexprの機能
比較するとconstexprの変数、関数constexprのは混乱し、より簡単にいくつかの場所を変更しました。
。場合; 1)constexprの受信パラメータがconstexprの変数を生成し、コンパイル時に計算することができる場合に、機能を変更し、着信パラメータはラントラバース(constexprの非存在)を生成、コンパイル時に計算することができません。
したがって、関数本体は、constexprの適用条件を存在する場合、それはconstexprのキーワードを追加する必要があり、二つの機能を記述する必要はありません。
例えば(実施例出典[3] )。
INT FOO constexprの(私はINT){ 私は+戻り5; } int型のmain(){ I = 10 int型; <(5)INT、FOO> STD ::アレイARR; // OK ,. 5は、定数式で算出されます(5)fooが定数式である のfoo(I); //呼び出しがある [OK]を、私は定数式ではないが、それでも(constexprのは無視されます)を呼び出すことができます はstd ::アレイ<int型、FOO(I)> ARR1; //エラーが、FOO(I)結果は定数式ではありません呼び出します }
14と11の間の2)C ++差
C ++ 11標準では、constexprの修飾された関数に対して定義され、過酷な条件である:関数の種類戻り値とパラメータのタイプの全ては、インビボでのリテラルの種類、および機能であり、唯一のreturnステートメントを有していなければなりません[ 1] 。
この条件は明らかになるように援助のconstexprのではあまりにも過酷なので、多くの操作のですか?:式、再帰と達成するために他の方法。
C ++ 14では、これが唯一残して、リラックスを定義これらの値はライン上のコンパイル時に決定することができる、つまり、「関数の戻り値とパラメータのタイプの任意のタイプは、リテラルタイプです」。
3. constexprのクラス(クラスリテラル)
ビルトインタイプは、リテラル定数であるが、時にはあなたは、コンストラクタをconstexprのように変更する必要がある上、この時間をタイプして、リテラル定数をカスタマイズする必要があります。
リテラルconstexprのクラスは、少なくとも1つのコンストラクタを提供する必要があります。
例えば:
クラスPoint { パブリック: constexprのポイント(ダブルXVAL = 0、二重yvalを指定= 0)、X(XVAL)、Y(yvalを指定){} constexprの二重のgetX()constは{戻りX;} constexprの二重のgetY()constは{Yを返します;} プライベート: ダブルX、Y。 }。
そのようなクラスが定義されている場合、リテラルを定義するためのタイプポイントの対象とすることができます。すなわち:
constexprの点P1(9.4、27,7); constexprの点P2(28.8、5.3); constexprの ポイント中点(CONSTポイント&P1、CONSTポイント&P2){ リターン{p1.getX()+ p2.getX()/ 2、p1.getY()+ p2.getY()/ 2}。 } constexprの自動ミッド=中間点(P1、P2)。
上記の例では、P1、P2はリテラル定数であり、中間点は、constexprの機能を変更し、従ってプロセス全体が中間完了することができ、両方のコンパイル時に、時間を実行しているソフトウェアは、自然に大幅に低減される。衝突さ
これまでのところ、メイン3が完了しているconstexprのを使用して要約上(constexprの変数、constexprの変更機能、constexprの変更コンストラクタ)に、以下のいくつかの考慮事項があります。
注1は、例えば、配列のサイズを確認するために、(私を含め)多くの人がgccのではコンパイル時に指定しなければならないことがわかった::
アレイは、メイン関数内で定義されている場合、それはあっても定数式が与えられていない、また、コンパイルすることができます。これはほとんど私の知識を覆します。。。
青色が大きくノウハウにほぼ答える[4] 、これを説明し、実際には、可変長配列C99です。グローバル変数(メモリを割り当てていない)で使用することができない、ローカル変数に使用することができ、参照は答えるために細部を共有することがあります。
注2: constexprのように複雑な、最後になぜ?
実際には、最初は効率のためです。効率は、彼らはコンパイラの最適化を思い出させることができるかを決定するために、コンパイル時、それは読み出し専用メモリ内に格納されていてもよいC ++の設計思想の一つであります
第二の変数は、constexprのは、上記指定された長さとしてアレイで使用することができるように宣言され、そしてテンプレートパラメータ、ケースラベルを含むなど、の使用を容易にされる[5] 。
参考文献:
1.スタンリー・B・リップマン/ジョゼ・ラジョイー/バーバラE.武、C ++プライマー中国語版(リリース5)[M]。電子工業プレス2013年
2.マイヤーズS.効果的な現代C ++ [M]。オライリー、2014。
「?C ++のconstとconstexprの間の差は」3質問の答えにはほとんど青知っている: https://www.zhihu.com/question/35614219
青色のノウハウ4.問題のほとんどの答え「constexprの差のconstの配列は?」: https://www.zhihu.com/question/29662350/answer/45192834
C ++の5 Stroustrup氏B. Aツアー[M]。アディソン・ウェスリー・ロングマン、アムステルダム、2013年。