テンプレートメタプログラミングの質問にこれほど遅く答えるべきではないでしょう。しかし、ここに行きます。
まず、constexprはVisual Studio 2012に実装されていません。Windows用に開発する場合は、忘れてください。私は知っている、それはひどい、私はそれを含まないためにマイクロソフトを嫌う。
それが邪魔にならないように、定数として宣言できるものはたくさんありますが、「コンパイル時にそれらを操作できる」という点では、実際には「定数」ではありません。例えば:
const int foo[5] = { 2, 5, 1, 9, 4 };
const int bar = foo[foo[2]]; // Fail!
コンパイル時にそこから読み取ることができると思いますよね?いいえ。しかし、あなたがそれをconstexprにすればあなたはそうすることができます。
constexpr int foo[5] = { 2, 5, 1, 9, 4 };
constexpr int bar = foo[foo[2]]; // Woohoo!
Constexprは、「定数伝播」の最適化に非常に適しています。つまり、コンパイル時に何らかの条件(おそらくメタプログラミング)に基づいて宣言された変数Xがある場合、それがconstexprである場合、コンパイラは、最適化を実行するときにそれを「安全に」使用できることを認識します。 a =(X * y);のような命令 そしてそれらをa=0に置き換えます。Xが0と評価された場合(および他の条件が満たされている場合)。
明らかに、これは素晴らしいことです。なぜなら、多くの数学関数では、定数の伝播により、(使いやすい)時期尚早の最適化が簡単にできるからです。
それらの主な用途は、かなり難解なこと(コンパイル時のバイトコードインタープリターをはるかに簡単に記述できるようにするなど)以外に、コンパイル時に呼び出して使用できる「関数」またはクラスを作成できるようにすることです。時間と実行時。
基本的には、C ++ 03の穴を埋めるだけで、コンパイラによる最適化に役立ちます。
では、あなたの3つのうちどれが「最高」ですか?
2は実行時に呼び出すことができますが、その他はコンパイル時のみです。それはかなり甘いです。
それにはもう少しあります。ウィキペディアには、「constexprでこれが可能」という非常に基本的な要約が記載されていますが、テンプレートメタプログラミングは複雑になる可能性があります。Constexprを使用すると、その一部がはるかに簡単になります。配列から読み取るという以外に、明確な例があればいいのにと思います。
良い数学的な例は、ユーザー定義の複素数クラスを実装したい場合だと思います。テンプレートメタプログラミングのみでconstexprを使用せずにコーディングするのは、桁違いに複雑になります。
では、いつconstexprを使用すべきではないのでしょうか。正直なところ、constexprは基本的に「MORECONSTを除くconst」です。通常、constを使用する場所であればどこでも使用できますが、実行時に呼び出されたときに、入力がconstでない場合に関数が非constとして動作する方法など、いくつかの注意点があります。
ええと OK、今のところこれですべてです。私はあまりにも疲れすぎて、これ以上言うことはできません。お役に立てば幸いです。お役に立てなかった場合は、遠慮なく反対票を投じてください。これを削除します。