2015-04-03 19 views
18

Tôi đang cố gắng biên dịch mã này, nhưng g ++ than phiền về ZERO có loại không đầy đủ. Điều này có nghĩa rằng trong C++ một struct không thể chứa một cá thể static constexpr của chính nó? Nếu vậy, tại sao?Trường C++ tĩnh constexpr với loại không đầy đủ

struct Cursor 
{ 
    size_t row,column; 

    static constexpr Cursor ZERO {0,0}; 
    //error: constexpr const Cursor Cursor::ZERO has incomplete type 
}; 

EDIT: Tôi hiểu rằng Cursor không thể có một loại hoàn toàn khi tôi tuyên bố ZERO. Điều tôi muốn biết là: có cách nào tôi có thể có ZERO thuộc về Cursor và vẫn đang là constexpr?

+0

thể bạn cung cấp thông báo lỗi? –

+2

Tôi nghi ngờ điều này là do khởi tạo constexpr & inline. – Quentin

+0

Di chuyển khởi tạo ra ngoài khai báo lớp. –

Trả lời

12

Thật không may, bạn chỉ đơn giản là không thể làm điều này!

Một số static constexpr thành viên có thể được khởi tạo inline:

[C++11 9.4.2/3]:[..] Một thành viên static dữ liệu loại đen có thể được khai báo trong định nghĩa lớp với constexpr specifier; nếu vậy, khai báo của nó phải chỉ định bộ khởi tạo dấu ngoặc đơn hoặc bằng nhau, trong đó mỗi mệnh đề khởi tạo là một biểu thức chuyển nhượng là một biểu thức không đổi. [..]

Cursor là một loại chữ, do đó, số này được tính.

Và việc sử dụng Cursor chính nó như là một thành viên static dữ liệu trong vòng loại của nó không phải là một vấn đề, miễn là bạn khởi nó tại từ vựng phạm vi không gian tên:

[C++11: 9.4.2/2]:Việc kê khai của một thành viên static dữ liệu trong định nghĩa lớp học của nó không phải là định nghĩa và có thể là một loại không đầy đủ ngoài khoảng không đủ điều kiện cv. Định nghĩa cho thành viên dữ liệu static sẽ xuất hiện trong phạm vi không gian tên kèm theo định nghĩa lớp của thành viên. Trong định nghĩa ở phạm vi không gian tên, tên của thành viên dữ liệu static phải đủ điều kiện theo tên lớp của nó bằng cách sử dụng toán tử ::. Trình khởi tạo trong định nghĩa của một thành viên dữ liệu static nằm trong phạm vi của lớp (3.3.7).

Nhưng bạn không thể làm điều đó với constexpr:

[C++11: 7.1.5/9]: Một specifier constexpr sử dụng trong một tuyên bố đối tượng tuyên bố đối tượng như const. Đối tượng đó phải có loại chữ và được khởi tạo. [..]

Tôi nghĩ rằng tất cả các từ ngữ này có thể được cải thiện nhưng, trong khi chờ đợi, tôi nghĩ rằng bạn sẽ cần phải thực hiện ZERO một tổ chức phi thành viên trong không gian tên kèm theo.

+2

Cảm ơn câu trả lời đầy đủ này. Cho rằng Cursor thực sự được định nghĩa bên trong lớp VGA, tôi sẽ chỉ làm cho ZERO là thành viên constexpr tĩnh của VGA. Đôi khi tôi thấy hạn chế nhất định khá khó chịu ... – lodo

5

có cách nào tôi có thể có ZERO thuộc về Con trỏ và vẫn đang là constexpr không?

Vâng, nếu bạn đếm lồng lớp con là "thuộc" lớp chứa:

struct Cursor 
{ 
    size_t row,column; 

    struct Constants; 
}; 

struct Cursor::Constants 
{ 
    static constexpr Cursor ZERO {0,0}; 
}; 
3

Bạn có thể nếu bạn chấp nhận để có một chức năng, không phải là một biến

struct Cursor 
{ 
    size_t row,column; 

    static constexpr Cursor ZERO() { return Cursor{0,0}; } 
}; 
Các vấn đề liên quan