Oto, co próbuję. MinGW g ++ 4.7.0.C++ 11 Inicjowanie klasy tablicy stałej statycznej
#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;
}
próbuję kompilowanie go i uzyskać poniżej wynik:
>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
Czy C++ 11 powinna umożliwić inicjowanie statyczną tablicę const w klasie jak to? Czy też musi być zdefiniowana poza klasą, tak jak przed C++ 11?
Hej, mam to samo pytanie, ale zastanawiam się, dlaczego linkery potrzebują tej linii? Czy C++ 11 nie obsługuje już członków init w definicji klasy? – liuyanghejerry
@liuyanghejerry Oto dwie oddzielne rzeczy tutaj. Pierwsza to inicjalizacja i jest dozwolona w nagłówku dla typów całkowitych od C++ 03. Jak widać, ta funkcja C++ została rozszerzona w C++ 11 dla innych typów, o ile są one constexpr. Drugą rzeczą jest miejsce w pamięci dla tych członków const. Jeśli weźmiesz adres takiej odmiany ('& Fruit :: VALUES [1]') to musi gdzieś istnieć. To "gdzieś" jest właśnie tą definicją w pliku źródłowym. – PiotrNycz
@liuyanghejerry Nie jestem pewien, czy jest to dozwolone przez C++ std, ale w gcc możesz pominąć tę definicję w pliku źródłowym, o ile nie używasz w żaden sposób adresu tej zmiennej - ale to nie jest łatwe - każda funkcja const referencyjny wymusza kompilator, aby wyszukać definicję stałej stałej. – PiotrNycz