11

constexpr 関数は return ステートメントだけで構成されている必要があり、すべての引数はコンパイル時に認識されている必要があります。

// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

なぜreturnステートメントだけですか?つまり、なぜこれが間違っているのですか?

// constexpr functions use recursion rather than iteration
constexpr int factorial(int n)
{
    int a = 222; //another variable
    return n <= 1 ? 1 : (n * factorial(n-1));
}
4

2 に答える 2

13

どうして:

constexprは C++11 のかなり新しく根本的な概念であり、主要な言語標準を完全に新しいものに移行するのは難しいためです。保守主義のルール。

C++1y (現在は C++14 を対象としています) の場合、あなたの例は合法です。-std=c++1yトランクのclangのヒントは、フラグの下ですでに実装しています。

于 2013-06-09T02:41:40.480 に答える
7

Andy Prowl が言うように、これは実装を簡素化します。それはおそらく「なぜ」に答えますが、それがどのように行われるかは述べていません。

戻り値のみを持つ関数、より具体的にはローカル変数を持たない関数は、コンパイラにとって特別な状況です。この関数は現在、単一の式で構成されています。関数の AST は単一のルートを持つだけで済みます。変数がないということは、この式を処理する本格的な仮想マシンがなくても評価できることを意味し、単純なツリー式評価器を使用できます。さまざまな理由から、コンパイラーはおそらくすでにそのようなエバリュエーターを持っているか、比較的簡単に作成できます (ツリー単純化パスになります)。

が式の中でのみ使用されていることを知っているとconstexpr、重要な単純化も提供されます。これにより、関数呼び出しであっても、関数 AST の各頂点が同じプロパティを持つことが保証されます。メカニズム全体constexprは、const フォールディングの一般化された形式です。また、コンパイラで常にこの高レベルで実行されるわけではありませんが、(完全な VM と比較して) 大きな労力を必要とせずに実装できることが保証されます。

「なぜ」の質問に戻ります。この制限は、主にベンダーのリソース制限によって引き起こされます。明記されているように、この機能は大がかりな作業ではないため、ベンダーは妥当な期間で実際に実装できます。そのような制限がない場合、特にローカル変数を許可すると、必要な作業量が大幅に増加します。ただし、ユーザー (私たちプログラマー) の観点からは、制限は完全に恣意的なものです。

于 2013-06-09T03:57:46.230 に答える