2012-11-04 53 views
8

這是我正在嘗試的。 MinGW g ++ 4.7.0。C++ 11初始化類靜態常量數組

#include <iostream> 
#include <string> 

class Fruit 
{ 
public: 
    enum Value { APPLE, ORANGE, BANANA, NONE }; 
    static const Value VALUES[4] = { APPLE, ORANGE, BANANA, NONE }; 
    Fruit (Value v = NONE) : v_(v) { }; 
    std::string to_string() const { 
     switch (v_) { 
      case APPLE: return "apple"; 
      case ORANGE: return "orange"; 
      case BANANA: return "banana"; 
      default: return "none"; 
     } 
    } 
private: 
    Value v_; 
}; 

int main (int argc, char * argv[]) 
{ 
    for (Fruit f : Fruit::VALUES) 
     std::cout << f.to_string() << std::endl; 
    return 0; 
} 

我嘗試編譯,並得到下面的輸出:

>g++ -std=c++0x test.cpp 
test.cpp:9:66: error: 'constexpr' needed for in-class initialization of static d 
ata member 'const Fruit::Value Fruit::VALUES [4]' of non-integral type [-fpermis 
sive] 


>g++ -std=c++0x -fpermissive test.cpp 
test.cpp:9:66: warning: 'constexpr' needed for in-class initialization of static 
data member 'const Fruit::Value Fruit::VALUES [4]' of non-integral type [-fperm 
issive] 
cc1l4Xgi.o:test.cpp:(.text+0x1a): undefined reference to `Fruit::VALUES' 
collect2.exe: error: ld returned 1 exit status 

是C++ 11應該允許這樣的類初始化靜態常量數組?還是必須像C++ 11之前一樣在類之外定義它?

回答

17

test.cpp:9:66: error: 'constexpr' needed for in-class initialization of static d ata member 'const Fruit::Value Fruit::VALUES [4]' of non-integral type [-fpermis sive]

編譯器告訴缺什麼:

class Fruit 
{ 
public: 
    enum Value { APPLE, ORANGE, BANANA, NONE }; 
    static constexpr Value VALUES[4] = { APPLE, ORANGE, BANANA, NONE }; 
    //  ^^^^^^^^^ 
... 
}; 

cc1l4Xgi.o:test.cpp:(.text+0x1a): undefined reference to `Fruit::VALUES'

爲了使連接器快樂,你必須在源文件中的某個地方加入這一行(不是頭文件):

constexpr Fruit::Value Fruit::VALUES[4]; 
+0

嘿,我有同樣的問題,但我想知道爲什麼連接器需要這一行? C++ 11是否已經在類定義中支持init成員? – liuyanghejerry

+2

@liuyanghejerry這裏有兩件獨立的事情。首先是初始化,並且自從C++ 03開始,它就被允許在整數類型的頭文件中。正如你所看到的,只要它們是constexpr,這個C++特性在C++ 11中被擴展用於其他類型。另一件事是爲這個const成員記憶一個房間。如果你拿這樣的變量的地址('&Fruit :: VALUES [1]'),它必須存在於某處。這個「某處」就是源文件中的這個定義。 – PiotrNycz

+0

@liuyanghejerry我不確定這是否被C++ std所允許,但是在gcc中,只要您不以任何方式使用此變量的地址,您可以跳過源代碼文件中的這個定義 - 但這並不容易 - 任何函數const引用強制編譯器查找const變量定義。 – PiotrNycz