序章
constexpr
constant-expressionを必要とするコンテキストで何かを評価できることを実装に伝える方法として導入されたわけではありません。準拠する実装は、C++11 より前にこれを証明できました。
実装で証明できないのは、特定のコードの意図です。
- 開発者がこのエンティティで表現したいことは何ですか?
- たまたま機能するという理由だけで、コードを定数式で使用することをやみくもに許可する必要がありますか?
なしでは世界はどうなるでしょうconstexpr
か?
ライブラリを開発していて、 interval 内のすべての整数の合計を計算できるようにしたいと考えているとします(0,N]
。
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
意図の欠如
コンパイラは、渡された引数が変換中にわかっている場合、上記の関数が定数式で呼び出し可能であることを簡単に証明できます。しかし、あなたはこれを意図として宣言していません - たまたまそうなっただけです。
ここで、他の誰かがやってきて、関数を読み取り、コンパイラと同じ分析を行います。「おお、この関数は定数式で使える!」、次のコードを記述します。
T arr[f(10)]; // freakin' magic
最適化
「すばらしい」ライブラリ開発者であるあなたは、f
が呼び出されたときに結果をキャッシュする必要があると判断します。同じ値のセットを何度も計算したいと思う人がいるでしょうか?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
結果
ばかげた最適化を導入することで、たまたま定数式が必要なコンテキストでの関数の使用をすべて中断しました。
関数が定数式で使用可能であると約束したconstexpr
ことはありません。そうでなければ、そのような約束を提供する方法はありません。
では、なぜ必要なのconstexpr
でしょうか?
constexprの主な使用法は、インテントを宣言することです。
エンティティが - としてマークされていない場合、それは定数式constexpr
で使用されることを意図したものではありません。たとえそうであったとしても、そのようなコンテキストを診断するためにコンパイラに依存しています (それは私たちの意図を無視するためです)。