2012-11-04 43 views
8

Đây là những gì tôi đang cố gắng. MinGW g ++ 4.7.0.C++ 11 Khởi tạo lớp mảng const tĩnh

#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; 
} 

tôi cố gắng biên dịch nó và nhận được đầu ra dưới đây:

>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 

là C++ 11 phải cho phép khởi tạo một mảng const tĩnh trong một lớp học như thế này? Hay nó phải được định nghĩa bên ngoài lớp như trước C++ 11?

Trả lời

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]

biên dịch nói với những gì đang mất tích:

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'

Để thực hiện mối liên kết hạnh phúc, bạn phải thêm dòng này ở đâu đó trong các tập tin nguồn (không tiêu đề tập tin):

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

Xin chào, tôi có cùng một câu hỏi nhưng tôi tự hỏi tại sao những người liên kết lại cần dòng này? Không C++ 11 đã hỗ trợ các thành viên init trong định nghĩa lớp? – liuyanghejerry

+2

@liuyanghejerry Đây là hai điều riêng biệt ở đây. Đầu tiên là khởi tạo và nó được cho phép trong tiêu đề cho các kiểu số nguyên kể từ C++ 03. Và như bạn có thể thấy, tính năng C++ này đã được mở rộng trong C++ 11 cho các loại khác miễn là chúng là constexpr. Điều khác là một căn phòng trong ký ức cho các thành viên const này. Nếu bạn lấy một địa chỉ của variale ('& Fruit :: VALUES [1]') nó phải tồn tại ở đâu đó. Điều này "một nơi nào đó" chỉ là định nghĩa này trong tập tin nguồn. – PiotrNycz

+0

@liuyanghejerry Tôi không chắc chắn nếu điều này được cho phép bởi C++ std nhưng trong gcc bạn có thể bỏ qua định nghĩa này trong tệp nguồn miễn là bạn không sử dụng địa chỉ của biến này theo bất kỳ cách nào - nhưng điều này không hề dễ dàng. const tham chiếu lực biên dịch để tìm định nghĩa biến const. – PiotrNycz

Các vấn đề liên quan