2015-10-18 17 views
9

tôi đã cố gắng để chuyển tiếp-khai báo một constexpr mẫu biến như thế này:Chuyển tiếp tuyên bố một mẫu biến constexpr

template<typename> 
constexpr std::size_t iterator_category_value; 

Mục đích là để ghi nhận rằng mỗi chuyên môn hóa nên constexpr nhưng tôi phải thừa nhận rằng tôi không bao giờ kiểm tra xem nó là hợp pháp hay không và g ++ đã hài lòng với nó. Tuy nhiên, khi tôi đã cố gắng để biên dịch Spinnet này với kêu vang ++ thay vào đó, tôi nhận được lỗi sau:

error: default initialization of an object of const type 'const std::size_t' (aka 'const unsigned long') 
    constexpr std::size_t iterator_category_value; 
         ^
                = 0 

Các lỗi có ý nghĩa, và loại bỏ constexpr làm cho nó biến mất, do đó không phải là một vấn đề thực sự. Tuy nhiên, tôi tò mò bây giờ: không tiêu chuẩn cho phép như vậy tuyên bố constexpr về phía trước cho một mẫu biến hoặc là nó bất hợp pháp? g ++ và clang ++ dường như không đồng ý và tôi muốn biết nơi tôi nên gửi báo cáo lỗi nếu cần.

Cả hai người trong số họ khiếu nại về biến số constepxr chuyển tiếp không phải là mẫu biến, vì vậy ngữ cảnh mẫu biến có vẻ là điều khiến các trình biên dịch không đồng ý.

+0

Nội dung của http://wg21.cmeerw.net/cwg/issue1712 ngụ ý rằng bạn không thể chuyển tiếp khai báo nó dưới dạng 'constexpr', tuy nhiên tôi không chắc chắn cách std cấm nó. Một mẫu biến không giống như một tuyên bố * đối tượng * với tôi. – dyp

+0

OTOH, [dcl.dcl] p9 có vẻ rất chung chung và nên áp dụng cho các mẫu biến (=> các mẫu biến là các khai báo đối tượng => 'constexpr' yêu cầu khởi tạo) – dyp

+0

@dyp Btw., Ý của bạn là" bây giờ "? Không phải bạn đang biên dịch các nguồn cập nhật nhất hiện có trên Git? – Columbo

Trả lời

8

Trong tiêu chuẩn C++ 14, có vẻ như khá rõ ràng rằng việc khởi tạo là bắt buộc. Từ phần 7.5.1 đoạn 9,

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.

Đối với ý nghĩa chính xác của "tuyên bố đối tượng", Mục 7 đoạn 7 trạng thái:

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type and an object declaration otherwise.

8

Clang là đúng. Các khai của một mẫu biến là một tuyên bố đối tượng ([dcl.dcl]/9), do đó nó phải cung cấp một initializer theo [dcl.constexpr]/9:

A constexpr specifier used in an object declaration declares the object as const . Such an object […] shall be initialized.

Có một cách hiệu quả là không có cách nào của "chuyển tiếp" tuyên bố một đối tượng là constexpr ở nơi đầu tiên, mặc dù; Nếu constexpr được áp dụng cho việc khai báo một biến, nó phải là một định nghĩa ([dcl.constexpr]/1).

+0

[Có gì thay đổi gần đây không?] (Http: // coliru. stacked-crooked.com/a/cb1d8ebe90a2bc11) – Orient

+0

Chỉ một mã có chứa trường hợp được thảo luận. Nó chứa khai báo chuyển tiếp của mẫu biến 'constexpr', nhưng biên dịch tốt. – Orient

+0

@Orient Bạn nhận ra rằng bạn đang biên dịch với trình biên dịch bị lỗi trong khía cạnh này? – Columbo

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