2017-12-07 28 views
5

xem xét mã này thử nghiệm tầm thường:Tại sao thuộc tính constexpr không hoạt động khi áp dụng cho một phương thức tĩnh?

class Test 
{ 
public: 
    Test() {/* empty */} 

private: 
    enum {BLAH = 42}; 

    static constexpr int Magic() {return BLAH*4;} 

    float f[Magic()]; 
}; 

int main(int argc, char ** argv) 
{ 
    Test t; 
    return 0; 
} 

Khi tôi cố gắng biên dịch nó (dưới hệ điều hành MacOS/X sử dụng kêu vang ++ từ XCode mới nhất), tôi có được điều này lỗi biên dịch:

Jeremys-Mac-Pro:~ jaf$ clang++ -std=c++11 ./test.cpp 
./test.cpp:11:14: error: fields must have a constant size: 'variable length 
     array in structure' extension will never be supported 
     float f[Magic()]; 

thể bất cứ ai giải thích tại sao đây là lỗi? Để so sánh, nếu tôi di chuyển phương thức Magic() ra khỏi lớp Test và làm cho nó trở thành một hàm tự do, nó biên dịch như mong đợi, nhưng tôi thực sự không muốn làm điều đó vì tôi muốn giữ Magic() và BLAH riêng tư đối với lớp Kiểm tra nếu có thể.

(Lưu ý: Tôi không cố gắng sử dụng các mảng chiều dài thay đổi ở đây, đúng hơn Tôi đang cố gắng để khai báo một mảng có kích thước được xác định bởi việc tính toán của một hàm tại thời gian biên dịch)

Trả lời

3

Đó là bởi vì các hàm trong một lớp không được xử lý cho đến khi lớp hoàn tất. Quy tắc này cho phép một hàm được định nghĩa trong một lớp để truy cập các thành viên của lớp đó được định nghĩa sau trong lớp so với hàm đó. Kết quả là, Magic() chưa có định nghĩa, do đó không thể đánh giá tại thời điểm biên dịch đó.

Đây là hành vi đúng, mặc dù lỗi mà các trình biên dịch khác nhau tạo ra không hữu ích cho việc tìm hiểu sự cố.

Các quy tắc chính thức là trong chuẩn C++ tại [class.member]/6:

A class is considered a completely-defined object type (6.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

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