2016-05-03 10 views
2

constexpr関数の場合、唯一のオプションは単純なもの以外のものに対して再帰関数を持たせることです。その問題は、実行時に再帰関数が高価になるということです(特に自分自身を何度も呼び出す場合)。同じ関数(インライン化またはconstexpr用)の2つのバージョン

だから、通常の使用のために2つの機能constexpr用とその他を実現することが可能である:

constexpr int fact(int x){ //Use this at compile time 
    return x == 0 ? 1 : fact(x-1)*x; 
} 

int fact(int x){ //Use this for real calls 
    int ret = 1; 
    for (int i = 1; i < x+1; i++){ 
    ret *= i; 
    } 
    return ret; 
} 

と同じラインに沿って、あなたはまた、インライン状況のための特別な機能を行うことができますか?

+0

実行時にコンパイル時の構造が高価になるのはなぜですか?コンパイルが難しいかもしれませんが、実行時には時間がかかりません。 –

+1

@ Loki例えば、私が渡しているものがわからない場合(実行時に計算できないユーザーからの入力など) – DarthRubik

+0

コンパイラがテールコールの最適化を提供しているかどうかを確認することができます。 [主要なものは最適化が行われたときに行う](https://stackoverflow.com/questions/34125/which-if-any-c-compilers-do-tail-recursion-optimization)(その情報は8年以上これは、再帰関数を明示的ループと同じように動作させます。 – ShadowRanger

答えて

3

C++ 14以降、ループフォームは有効なconstexprhttp://en.cppreference.com/w/cpp/language/constexpr)であるため、constexprの2番目のフォームが有効です。 残念ながら、すべてのコンパイラがこれをサポートしているわけではありません(Visual C++の最新バージョンはありませんが、最近のClangとGCCのものは明らかですが、これはテストできません)。いずれかのことができます場合は

  • コンパイラの最適化に依存し、最初のバージョン(あなたが特定のコンパイラのためにこれをテストしたい場合があります)
  • を使用すると、2つのフォームに異なる名前を付けます( constexpr関数の場合はfact_constのようになり、引数がconstexprの場合はconstexprバージョンのみを使用するようにしてください(これが実際にどうかを確認する方法はわかりません)
  • コンパイラがこれをサポートします。
関連する問題