2017-02-26 3 views
1

もっと一般的なconst入力パラメータをfibonacciのconstexpr実装に渡そうとしています。テンプレートのパラメータをintに置き換えると、物事はもう一度hunky-doryになります。constexprへのテンプレートパラメータ

#include<iostream> 
template <typename T> 
constexpr auto fib_ce(T n) { 
    return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1; 
} 

int main() { 
    std::cout<<fib_ce(4)<<"\n"; 
} 

これは私が取得エラーです:

g++ -std=c++14 -o constexpr_fib constexpr_fib.cpp 
constexpr_fib.cpp:4:19: fatal error: recursive template instantiation exceeded maximum depth of 256 
    return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1; 

      ^

私はこのconstexprのために、long int型、unsigned long型、などなどのような入力を取ることができconstexprのにテンプレート引数を提供するにはどうすればよい

+0

あなたはそれを動作させるために、このようにそれを働かせることができる: '場合(N <= 1)リターンT {1 }; return fib_ce ... '。 –

+0

条件の両辺を評価するので、これは問題だと思います。 –

答えて

3

ルール[dcl.spec.auto]である:

undeducedプレースホルダタイプを持つエンティティのタイプは、発現のタイプを決定するために必要とされる場合、 プログラムが不正です。

これは、無限の再帰的控除である可能性のある任意の複雑さを短くカットすることです。

  1. ちょうどTの代わりautoを使用します:非捨てたら

    template <class T> 
    constexpr T fib_ce(T n) { 
        return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1; 
    } 
    
  2. 我々はまた、ルールを持っている恐怖しかし、この問題を回避する方法がありません関数内でreturnステートメントが見られましたが、そのステートメントから導かれる戻り値の型は、他の戻り値 を含む残りの関数で使用できます物語。

    したがって、条件演算子の代わりにifステートメントを使用できます。私達はちょうど、既知のタイプとreturn文が最初に行くようにロジックを反転する必要があります。

    template <typename T> 
    constexpr auto fib_ce(T n) { 
        if (n <= 1) { 
         return static_cast<T>(1);  // ok, deduced as T 
        } 
        else { 
         return fib_ce(n-1)+fib_ce(n-2); // we already deduced T, so sticking with it 
        } 
    } 
    
3

私は答えを見つけたと思います。自動化を控え、コンパイラに戻り値の型を渡す必要があります。以下では正常に動作:

#include<iostream> 
template <typename T> 
constexpr T fib_ce(T n) { 
    return (n>1) ? fib_ce(n-1)+fib_ce(n-2) : 1; 
} 

int main() { 
    std::cout<<fib_ce(4)<<"\n"; 
} 
関連する問題