2015-03-02 68 views
4

這更多的是一個哲學問題而不是實用的代碼片段,但也許C++大師可以啓發我(並且,如果已經被問到,請道歉)。constexpr的用途

我一直在閱讀Meyers的「Effective Modern C++」一書中的第15項,以及此線程:implicit constexpr?(加上合理數量的谷歌搜索)。該項目結束使用constexpr表達式,即它定義的功能可以返回給定編譯時間輸入的編譯時間值。另外,我提到的StackOverflow線程表明,一些編譯器完全能夠自己弄清楚編譯時哪些函數調用結果是已知的。

因此,問題:爲什麼constexpr被添加到標準,而編譯器應該派生並允許靜態/編譯時值定義?

我意識到它使各種編譯(例如std::array<T, constexpr>)定義不太可預測,但另一方面,根據邁爾斯的書,constexpr是接口的一部分,...,如果你刪除它,你可能會導致任意大量的客戶端代碼停止編譯。 因此,不僅要明確要求人們記住添加它,還要向界面添加永久性語義。

澄清:這個問題不是關於爲什麼應該使用constexpr。我明白,有能力以編程方式派生編譯時間值是非常有用的,並且在很多情況下我自己使用它。這是一個問題,爲什麼它在編譯器可能自行推斷const-time行爲的情況下是強制性的。

說明沒有。 2:這是一段代碼片斷,顯示編譯器不會自動推斷出這種情況,在這種情況下,我使用了g ++。

#include <array> 

size_t test() 
    { 
    return 42; 
    } 

int main() 
    { 
    auto i = test(); 
    std::array<int, i> arrayTst; 
    arrayTst[1] = 20; 
    return arrayTst[1]; 
    } 

std::array聲明編譯失敗,因爲還沒有定義test()constexpr,這當然是按照標準。如果標準不同,沒有任何東西可以阻止gcc獨立判斷test()總是返回一個常量表達式。

這個問題並沒有問「標準定義什麼」,而是「爲什麼標準是它的樣子」?

+0

可能有幫助:http://www.stroustrup.com/C++11FAQ.html#constexpr。 – 2015-03-02 23:20:08

+0

如果你的代碼從簡單易懂的參數中自動計算出來的話,那麼魔法值是不好的,如果你的代碼自動地從容易理解的參數中計算出來,那麼這是一個很大的勝利。例如,我編寫了一些代碼,以便在編譯時使用constexpr在編譯時計算crc32,並且我認爲對可以清楚地遵循的constexpr函數調用的可讀性要高得多,而不是計算誰知道如何的魔法值。你還可以在編譯時得到*保證*,這實際上在靜態全局初始化不運行的情況下實際上挽救了我的生命。 – tux3 2015-03-02 23:21:08

+0

@ tux3:當然,但沒有理由不能使用普通的(非'constexpr'函數)來做同樣的事情。 – 2015-03-02 23:22:29

回答

5

constexpr之前,編譯器有時可以找出編譯時間常量並使用它。但是,程序員永遠無法知道什麼時候會發生。

之後,程序員立即被告知表達式是否不是編譯時間常量,並且他或她意識到需要修復它。

+0

感謝您的快速回答。假設性地說,爲什麼'constexpr'不可選?也就是說,如果我覺得這樣的傾向,我可以添加關鍵字得到通知,如果表達式不是恆定的(如你所述),但仍獲得編譯時評估的好處,如果我忽略它(包括模板ARGS等) – RomanK 2015-03-02 23:24:15

+0

@RomanK :你有證據證明你沒有得到嗎? – 2015-03-03 01:17:40

+0

是的,我在這個問題上增加了一個例子。如果編譯器做到了,那將違背標準。 – RomanK 2015-03-03 06:43:01