2015-11-01 33 views
18

例如:我們可以在constexpr函數中忽略局部變量的const嗎?

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    // Can we omit const? 
    const int x = g(); 
    const int y = 10; 

    return x + y; 
} 

任何一點永遠const一個constexpr函數聲明局部變量?

是不是constexpr功能與const局部變量相當於到那些沒有const

換句話說,constexpr上的函數對其局部變量強加(暗示)const

+9

我不同意你忽略'const'使函數看起來更「乾淨」的前提。另外,不,我不這麼認爲。但我不是'constexpr't。 –

+3

你甚至可以[改變它們](http://ideone.com/L4Oa68)! (和它的邏輯,它不會使函數_不純粹) – Lol4t0

+2

@LeoHeinsaar我認爲你的意思是更少的非空白字符,因爲否則它可以通過該定義簡單地變得更「乾淨」,以幾乎普遍被解釋爲不可讀的方式。 – hvd

回答

23

在非constexpr函數變量聲明爲const也適用於constexpr功能相同的參數:

  • 聲明一個變量const記載的事實,它永遠不會改變。這在某些情況下可能有助於使該功能更具可讀性。
  • 聲明變量const會影響超載分辨率,並且可能會使h(x)解決h的不同,具體取決於x是否爲const

當然,在相反的方向,如在評論已經提到的:

即使在constexpr功能,局部變量可以被改變。如果這些變量被更改爲const,則嘗試更改它們將不再被接受。

+0

我認爲這是一個很好的答案。如果不加思索,可能會產生這樣一種印象:函數上的'constexpr'在某種程度上強加(隱含)了常量,包括局部變量(因爲,例如,您不能從中調用非constexpr函數)。謝謝。 –

+4

當然,const返回時不能移動const局部變量。出於這個原因,我對於當地人非常警惕。 –

1

通常,函數無法在編譯時進行評估,因此無法在常量表達式中調用。將函數指定爲constexpr表示可以在常量表達式中使用它,如果其輸入參數是常量。例如,這...

constexpr int n = func(7); 

...必須在編譯時進行評估。

這就是函數之前constexpr的含義。在這種情況下,它並不遵循函數內部的局部變量不必指定爲const。

16

這個具體的例子中的局部變量將最佳聲明constexpr,不const,因爲他們可以在編譯時計算:

constexpr int g() { return 30; }  

constexpr int f() 
{ 
    constexpr int x = g(); 
    constexpr int y = 10; 

    return x + y; 
} 

f()被稱爲在運行時,不constexprxy(有或沒有constxy)你給編譯器選項初始化xy在運行時而不是編譯時。隨着constexprxy,編譯器計算xy在編譯時,即使f()在運行時執行。

然而,在不同的功能中,不能總是使用constexpr。例如,如果f()g()了一個參數:

constexpr int g(int z) { return z+30; }  

constexpr int f(int z) 
{ 
    const int x = g(z); 
    constexpr int y = 10; 

    return x + y; 
} 

現在x不能標記爲constexpr,因爲z可能不是一個編譯時間常數,目前還沒有辦法將其標記爲此類。所以在這種情況下,標記xconst是你能做的最好的。

+1

要求在沒有改變的局部變量上隱含'constexpr'是否合理? –

+0

@LeoHeinsaar:恐怕沒有。在這個例子中,如果'g()'沒有標記爲'constexpr'呢?在這種情況下,結果'x'不能被標記爲'constexpr',編譯器在運行時有權計算'g()'。也許'g()'需要打個電話才能得到結果... –

+1

如果g()沒有標記爲'constexpr',那麼它甚至應該編譯?我理解的方式是,我們只能從'constexpr'函數調用'constexpr'函數... –

3

你不僅可以,但有時你必須如果變量的變化),

constexpr size_t f(size_t n) { 
    size_t val = 1; 
    if (n == 0) val++; 
    return val; 
} 
char arr0[f(0)] = {'a', 'x'}; 
char arr1[f(1)] = {'y'}; 

是C++ 14的罰款。

相關問題