2015-06-14 283 views
2

我有以下代碼:未定義參考

#include<chrono> 
#include<iostream> 

using namespace std::chrono_literals; 

#define MSG "hello" 
#define DUR 1000ms 

class mwe{ 
    public: 
    static constexpr auto msg = MSG; 
    static constexpr auto dur_1 = DUR; 
    static constexpr std::chrono::milliseconds dur_2 = DUR; 
    static const std::chrono::milliseconds dur_3; 
    static constexpr decltype(DUR) dur_4 = DUR; 
}; 

constexpr std::chrono::milliseconds mwe::dur_2; 
const std::chrono::milliseconds mwe::dur_3 = DUR; 
constexpr decltype(DUR) mwe::dur_4; 

int main(void) { 
    std::cout << "str: " << mwe::msg << std::endl; 
    std::cout << "dur_1: " << mwe::dur_1.count() << std::endl; 
    std::cout << "dur_2: " << mwe::dur_2.count() << std::endl; 
    std::cout << "dur_3: " << mwe::dur_3.count() << std::endl; 
    std::cout << "dur_4: " << mwe::dur_4.count() << std::endl; 
} 

如果我編譯它(G ++ 4.9),通過

g++ -std=c++14 -O2 test.cpp 

一切工作像預期,但如果我通過

g++ -std=c++14 -O0 test.cpp 

編譯我收到以下錯誤:

undefined reference to `mwe::dur_1' 

我個人喜歡這種方式,dur_1被定義並聲明最多,但如果沒有啓用優化,它在我的版本中不適用於g ++。 因爲我知道的所有其他方式(dur_2,dur_3,dur_4)都有它們的缺點(值的冗餘,如果我例如將1000ms更改爲1s,則aso。)。

你知道嗎if這是一個海灣合作委員會的錯誤,編譯工作生產模式,但沒有優化沒有工作?

有沒有可能的方法來獲得這個工作,而不需要在類之外定義dur_x的位置?

+0

'dur_1' _isn't_定義。不確定你的預期。 –

回答

6

這不是編譯器中的錯誤;這是你的錯誤。

odr-useddur1但從來沒有定義它。並且,不,constexpr和內聯初始化程序都不會將該聲明定義爲一個定義。

[C++11, C++14: 9.4.2/3]: If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.

與往常一樣,優化級別可能會影響編譯器能夠和/或願意報告此類錯誤的程度。

您可以編寫以下,以避免所謂的「問題」你確定:

#include<chrono> 

using namespace std::chrono_literals; 

#define DUR 1000ms 

struct T 
{ 
    static constexpr auto dur_1 = DUR; 
}; 

constexpr decltype(T::dur_1) T::dur_1; 
+0

我不明白爲什麼g ++需要'dur_1'的定義中的'constexpr'。 – dyp

+0

@dyp:在我看來,他們誤讀了[[dcl.constexpr]/1',它巧妙地要求所有的'constexpr'聲明_except_ this case –

+0

@dyp:http://stackoverflow.com/q/30831567/560648 –