2017-08-10 94 views
3

我使用constexpr得到斐波那契數斐波那契使用constexpr函數(編譯時間與運行時間)

枚舉用於計算

#include <iostream> 

constexpr long fibonacci(long long n) 
{ 
    return n < 1 ? -1 : 
     (n == 1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2)); 
} 

enum Fibonacci 
{ 
    Ninth = fibonacci(9), 
    Tenth = fibonacci(10), 
    Thirtytwo = fibonacci(32) 

}; 

int main() 
{ 
    std::cout << Fibonacci(Thirtytwo); 
    // std::cout << fibonacci(32); 
    return 0; 
} 

我收到以下錯誤編譯時斐波那契上執行的:

 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(30)' 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(6): note: while evaluating 'fibonacci(31)' 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(31)' 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): error C2131: expression did not evaluate to a constant 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(5): note: failure was caused by control reaching the end of a constexpr function 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(12): note: while evaluating 'fibonacci(32)' 
1>c:\users\hsingh\documents\visual studio 2017\projects\consoleapplication4\consoleapplication4\source.cpp(14): error C2057: expected constant expression 
1>Done building project "ConsoleApplication4.vcxproj" -- FAILED. 

但是當我使用運行時間 INT X = 30,Y = 2 ; 的std ::法院< <斐波納契(X + Y); //斐波那契是在運行時計算

Run Time with memory

我不會說我有一個問題,但我有一些困惑,如:

  1. 是內存使用的編譯時和運行時使用的constexpr不同?
  2. 如何知道停止利用或使用編譯時數據的位置?
  3. 我仍然試圖做的是如何利用編譯時間和運行時間的優勢共同完成類似Fibo的計算(使用編譯直到可以和之後,讓剩餘的計算在運行時完成)。

任何示例或參考(如果可用)都將有所幫助。

+0

你是什麼意思「當我使用運行時間」?是不是完全相同的代碼(減兩行)? – user463035818

+0

std :: cout << fibonacci(32);它的運行時間計算 –

+0

可能或可能不是[編譯時何時評估constexpr函數?](https://stackoverflow.com/q/14248235/11683) – GSerg

回答

5
  1. 內存的纖維蛋白原在編譯使用constexpr功能時間依賴於實現,但通常應該與運行時相比(大多數編譯器會編譯和執行語句)。

  2. 理論上,您應儘可能使用編譯時計算的表達式。在實踐中,這是一個判斷的呼喚(對SE的問題來說也許是個好主題),因爲不利的一面是編譯時間增加(可能是內存),缺乏調試。

  3. 看來你已經達到了編譯時表達式中MSVC允許的最大遞歸限制。我找不到有關此限制的任何文檔,但可以在其他編譯器上配置。您的錯誤是enum要求在編譯時完全評估的結果,因爲cout調用允許它在編譯時和/或運行時執行(如果生成程序集,則應該看到編譯時生成的常量較低的號碼呼叫以及用於高數量呼叫的遞歸功能)。

2

錯誤的原因是,你正在試圖計算Fib數爲32的Fib數。這是太多了!

您遇到了constexpr函數遞歸的最大限制,因此您會看到編譯錯誤。

在運行時程序會崩潰,在這一點上,但它不會因爲你的運行表現是不同的 - 這是32

+0

請問您可以添加更多信息我在運行時所犯的錯誤 –

+0

斐波納契(32)在enum和cout <<斐波納契(32)是不是都相同?這兩個調用相同的函數 –

+1

@HariomSingh,在枚舉'ThirtyTwo'中**已經是**應用於數字'32'的Fib函數的結果。 – SergeyA