2014-12-16 25 views
53

Đây là phần tiếp theo của câu hỏi này: Is it legal to declare a constexpr initializer_list object?.Tại sao không phải `std :: initializer_list` được định nghĩa là một loại chữ?

Vì C++ 14, lớp std::initializer_list có tất cả các phương pháp được đánh dấu bằng constexpr. Có vẻ tự nhiên để có thể khởi tạo một cá thể bằng cách thực hiện constexpr std::initializer_list<int> list = {1, 2, 3}; nhưng Clang 3.5 phàn nàn về list không được khởi tạo bằng biểu thức không đổi. As dyp pointed out in a comment, bất kỳ yêu cầu nào đối với std::initializer_list là kiểu chữ dường như đã biến mất khỏi các thông số kỹ thuật.

Điểm của việc có một lớp được định nghĩa đầy đủ là constexpr nếu chúng ta thậm chí không thể khởi tạo nó như vậy? Đây có phải là sự giám sát trong tiêu chuẩn và sẽ được sửa chữa trong tương lai không?

+0

Richard Smith dường như ngụ ý [ở đây] (http: //clang-developers.42468.n3.nabble.com/C-11-constexpr-và-initializer-list-td4031078.html) rằng 'std :: initializer_list' đã được tạo thành một kiểu chữ. Tuy nhiên, tôi không thể tìm thấy yêu cầu như vậy trong Tiêu chuẩn. Một câu hỏi thứ hai, mà tôi đã đăng trên một bình luận cho câu hỏi của tôi được liên kết ở trên, là * "Có thể khai báo các hàm thành viên không phải là tĩnh không?" *, Xem [CWG DR 1684] (http: //open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684) – dyp

+0

Điều này thật kỳ quặc, clang ++ biên dịch nó khi bạn đặt nó trong phạm vi toàn cầu: http://coliru.stacked-crooked.com/a/dab2834181fb8ea4 (Đây là [clang bug 15117] (http://llvm.org/bugs/show_bug.cgi?id=15117)) Mùi giống như một lỗi trình biên dịch khác đối với tôi. – dyp

+0

clang ++ cũng chấp nhận nó khi nó là biến tĩnh cục bộ: http://coliru.stacked-crooked.com/a/700cf33e2446b63c – dyp

Trả lời

5

Ủy ban tiêu chuẩn dường như có ý định trên initializer_list là một loại chữ. Tuy nhiên, nó không giống như một yêu cầu rõ ràng, và có vẻ là một lỗi trong tiêu chuẩn.

Từ § 3.9.10.5:

Một loại là một chữ kiểunếu nó là:
- một kiểu lớp (khoản 9) mà có tất cả các thuộc tính sau:
- - nó có một destructor tầm thường,
- - đó là một loại tổng hợp (8.5.1) hoặc có ít nhất một constexpr constructor hoặc constructor mẫu đó không phải là một bản sao hoặc di chuyển constructor, và
- - tất cả các phi của nó thành viên dữ liệu s và các lớp cơ sở là các kiểu chữ không bay hơi.

Từ § 18.9.1:

namespace std { 
    template<class E> class initializer_list { 
    public: 
    /* code removed */ 
    constexpr initializer_list() noexcept; 
    // No destructor given, so trivial 
    /* code removed */ 
    }; 
} 

này đáp ứng các yêu cầu đầu tiên và thứ hai.

Đối với yêu cầu thứ ba mặc dù:

Từ § 18.9.2 (tôi nhấn mạnh):

Một đối tượng của loại initializer_list<E> cung cấp quyền truy cập vào một mảng các đối tượng của loại const E. [Lưu ý: Một cặp con trỏ hoặc một con trỏ cộng với độ dài sẽ là các biểu diễn rõ ràng cho initializer_list. initializer_list được sử dụng để triển khai danh sách trình khởi tạo như được chỉ định trong 8.5.4. Sao chép danh sách trình khởi tạo không sao chép các phần tử cơ bản.
-end note]

Vì vậy, không có yêu cầu cho các thành viên private của việc thực hiện initializer_list là loại đen non-volatile; Tuy nhiên, bởi vì họ đề cập rằng họ tin rằng một cặp con trỏ hoặc một con trỏ và độ dài sẽ là "đại diện rõ ràng", họ có thể không cho rằng ai đó có thể đặt thứ gì đó không theo nghĩa đen trong các thành viên initializer_list.

Tôi muốn nói rằng đó là cả lỗi trong tiếng lóng và tiêu chuẩn, có thể.

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