2014-12-07 71 views
21

我有一個文件Dimension.h類Dimension,我定義(如同我所有的類):是否可以在頭文件中聲明constexpr類並將其定義在單獨的.cpp文件中?

class Dimension 
{ 
public: 

    constexpr Dimension() noexcept; 

    constexpr Dimension(int w, int h) noexcept; 

    int width; 
    int height; 

}; 

我以爲我可以像在我所有的班,把定義在一個單獨的Dimension.cpp :

#include "Dimension.h" 

constexpr Dimension::Dimension() noexcept : width(0), height(0) {} 

constexpr Dimension::Dimension(int w, int h) noexcept : width(w), height(h) {} 

但是當我嘗試使用類,編譯器告訴我:

警告:使用內聯函數「constexpr Dimension::Dimension()」,但從未定義

和同時連接:

未定義提及 'pong::graphics::Dimension::Dimension()'

(同與其他的構造函數)

如果我定義類在頭像這樣:

class Dimension 
{ 
public: 

    constexpr Dimension() noexcept : width(0), height(0) {} 

    constexpr Dimension(int w, int h) noexcept : width(w), height(h) {} 

    int width; 
    int height; 

}; 

並省略.cpp文件,一切工作正常。

我正在使用GCC 4.9.2。爲什麼單獨的定義不起作用?

+7

「constexpr」函數的要點是允許在編譯時評估函數。如果編譯器無法看到所述函數的主體,那麼這將是相當困難的。 – 2014-12-07 17:13:12

+2

_「爲什麼單獨的定義不起作用?」 - 因爲語言不允許。接受它,正確地做,繼續前進。 – 2014-12-07 17:13:14

+0

我已經懷疑過,但我不太確定我是否可以解釋(可能是參考)爲什麼它確切發生。我在Google上搜索時沒有發現任何關於此的內容,所以我想出了一個新問題,因爲這是合適的。 – 2014-12-07 17:19:28

回答

27

如果沒有在頭文件中定義constexpr函數,編譯器在編譯所有其他源文件時無法看到constexpr函數的定義。

很明顯,如果它看不到函數的定義,它就不能執行在編譯時計算它們所需的步驟。因此,所有constexpr函數都必須在使用它們的任何地方定義。

感謝@IgorTandetnik:
[dcl.constexpr]§7.1.5/ 2

constexpr功能和構造constexpr隱含直列。

[basic.def.odr]§3.2/ 4

內聯函數應每翻譯單元,其中它是ODR使用的限定。

5

你問可以取得什麼成就,有顯著限制:constexpr功能就只能從它被定義翻譯單元(即源文件)中被調用。這不適用於您給出的示例,因爲構造函數旨在成爲類的公共接口的一部分。然而,在其他情況下它可能非常有用,例如將私有方法定義爲constexpr然後在編譯時需要知道的表達式中使用它們的返回值,例如,模板實例化,開關語句標籤等。

相關問題