C++ 14では、constexprからより多くの制限が削除されていると思います。しかし、N3797 7.1.5によると3点:
Contexpr関数の定義は、次の制約を満たします。
静的なスレッドストレージ期間変数が許可されていない理由はわかっていますが、理由はわかりません。リテラル型の変数の定義のみが許可されているのはなぜですか。
または私は標準を理解していません。
よくわかりませんが、標準に従って、C++ 14でも次のエラーが発生するはずです。
struct point{
constexpr point(): x(0), y(0){}
constexpr point(int x_, int y_): x(x_),y(y_){}
constexpr int hypot()const { return x*x + y*y; }
int x,y;
};
constexpr int hypot(int x, int y) {
point p{x,y}; //error, because p - is not literal type.
return p.hypot();
}
// error, because return type is not literal.
constexpr point getPoint(int x, int y) { return {x,y}; }
// error, because parameter is not literal.
constexpr int hypot(point p) { return p.hypot(); }
Q:本当に上記のエラーが発生する場合、なぜこれらの制限が削除されないのですか?
リテラルタイプは3.9/10で定義されています:
タイプはリテラルタイプの場合:
void
;またはスカラー型。または
参照型。または
リテラル型の配列。または
次のすべてのプロパティを持つクラスタイプ(第9節):
些細なデストラクタがあり、
集計タイプ(8.5.1)であるか、コピーまたは移動コンストラクターではない
constexpr
コンストラクターまたはコンストラクターテンプレートが少なくとも1つあります。その非静的データメンバーと基本クラスはすべて、不揮発性リテラルタイプです。
したがって、構造体point
isリテラル型であり、サンプルコードは有効なC++ 1yです。
constexpr
関数がリテラル型の変数に制限されている理由については、コンパイル時に解釈可能であることが保証されているのはこれらの型だけです。