2015-10-13 102 views
2

所以一般constexpr函數功能,即在編譯時執行,當傳遞給它的參數也constexpr所以以下:constexpr函數和硬編碼參數

constexpr int function(int x, int y){ 
    return x+y; 
} 

與聲明的參數如下:

constexpr int x = 5; 
constexpr int y = 6; 

將在編譯時執行,但隨着參數如下聲明:

int x=5; 
int y=6; 

它不會。我在想,如果我們在接下來的方式調用這個函數會發生什麼:

function(5,6); 

從圖5的技術點和6是右值,但也沒辦法(我猜),他們可以強制轉換爲constexpr(如果我們可以一般地說關於鑄造到constexpr),所以我認爲它會在運行時執行。但是,在編譯時間內x和y都是已知的,因此在運行時沒有實際的理由來執行它。

所以我的問題是它是如何在現實生活中?將這個函數在運行時被執行或編譯時

+4

文字也是不變的表達。 –

+0

如果是這樣,請將其作爲回答發佈,我將接受它:) – DawidPi

+0

如果優化程序在編譯時也可能會調用帶有非常量「x」和「y」的調用'function(x,y)'意識到'x'和'y'將始終具有相同的值。它不需要這樣做,並且在需要'constexpr'的地方不能使用結果。 –

回答

2
constexpr int fun(int x, int y) { return x+y; } 
fun(5,6) // << constant expression? 

TL;博士

56是常量表達式。因此fun(5,6)也是一個常量表達式,將在編譯時評估,這是必需的(例如非類型模板)。

東西... 我有一個快速查看標準,我希望我沒有錯過任何重要的觀點。

我們已經知道從@ 42的回答是:

  • 據N4527 int是一個constexpr功能有效的放慢參數類型,因爲它是一個文本類型(因爲它是一個標量類型,是由同一文檔的一個3.9/10字面類型)。因此,fun是一個有效的constexpr函數。

  • 它提供的代碼將fun(5,6)放入需要常量表達式的上下文中,並且它似乎被某些編譯器接受。

現在的問題是這是否有效,符合標準的行爲。

§5.20從N4527說:

甲條件表達式e是一個芯常量表達式除非e的評價,如下所述抽象機(1.9)的規定,將評估的一個下面的表達式:

  • 這裏來的東西,阻止核常量表達式
表達式的大名單

該列表不包含「具有常量表達式參數的constexpr函數」,因此它是核心常量表達式(除非它們在使用時未定義)。

因此,如果56是常量表達式,然後fun(5,6)爲常量表達式如果fun是一個有效的constexpr功能和使用它之前被定義。給定的函數滿足§7.1.5/ 3中的要求約束,並且是有效的constexpr函數

兩個56整數常量int類型的按§2.13.2

1)的整數文字是不具有周期或指數部分數字序列,可選的分離單在確定其價值時被忽略的引號。 [...]

2)整數常量的類型是表5中相應列表中的第一個,其值可以表示。

後綴:none,十進制文字:intlong intlong long int

現在看看§5.20再次我們看到:這兩個是常量表達式。

+0

「因此,如果5和6是常量表達式,那麼fun(5,6)是一個常量表達式,如果fun聲明爲constexpr並且在使用它之前被定義。 ......不知道你必須知道在它的身體裏做了些什麼「樂趣」來作出判斷 - 檢查[this](http://stackoverflow.com/q/23775705/2352671)。你已經結束了一個簡單的問題 – 101010

+0

@ 101010是的,該函數必須是一個有效的constexpr函數。 – Pixelchemist

2

根據該草案標準N45277.1.5/3 constexpr符[dcl.constexpr]重點礦山):

一個constexpr函數的定義應該滿足以下約束:

(3.1) - 它不應該是虛擬的(10.3);

(3.2) - 其返回類型應爲文字類型;

(3.3) - 它的每個參數類型應該是一個文字類型;

...

因此,呼籲function(5,6);滿足一個constexpr功能和執行的定義將發生在編譯時。

此外,你可以通過使用std::integral_constant自己測試一下:

#include <iostream> 
#include <type_traits> 

constexpr int fun(int x, int y) { 
    return x + y; 
} 

int main() { 
    std::cout << std::integral_constant<int, fun(5, 6)>::value << std::endl; 
} 

LIVE DEMO

如果fun輸入參數不constexpr編譯失敗。

+0

酷我不知道,謝謝 – DawidPi

+2

「它是有效/保證,因爲它編譯」不是一個很好的論點。可能是編譯器擴展,編譯器錯誤或其他。 – Pixelchemist

+0

@Pixelchemist'std :: integral_constant'不是編譯器擴展。它在標準[20.10.2標題摘要[meta.type.synop] ]。 – 101010