2014-11-04 29 views
10
#include <iostream> 
#include <array> 

int main(int argc, char **argv) { 
    constexpr const std::array<int, 2> arr {{ 0, 1 }}; 
    constexpr const int arr2[] = { 0, 1}; 

    static_assert(arr[0] == arr2[0], "asdf"); 
    static_assert(arr[1] == arr2[1], "asdfasdf"); 

    return 0; 
} 

Khi biên soạn với gcc 4.8.24.9.1 sử dụng g++ test.cpp --std=c++11, biên soạn thành công. Khi biên soạn với clang 3.43.5 sử dụng clang++ test.cpp --std=c++11 Tuy nhiên, việc biên soạn thất bại:constexpr std :: mảng với static_assert

test.cpp:8:16: error: static_assert expression is not an integral constant expression 
     static_assert(arr[0] == arr2[0], "asdf"); 
         ^~~~~~~~~~~~~~~~~ 
test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used in a constant expression 

Vì vậy, câu hỏi của tôi là, mà trình biên dịch là "đúng" theo nghĩa là phù hợp với C++ 11? Và, nếu clang là chính xác, thì tại sao std :: mảng operator[] không có khả năng constexpr? Đó không phải là một trong những điều mà std::array được cho là sẽ giúp giải quyết?

Trả lời

9

Dường như clang là đúng, operator [] không phải là một constexpr trong C++ 11 nhưng là một constexpr trong C++ 14

constexpr const_reference operator[](size_type pos) const; (since C++14) 

để biên soạn với -std=c++14 nên làm việc mặc dù (see it live).

Trong C++11 draft standard phần 23.3.2.1lớp tổng quan về mẫu mảng có sau cho operator []:

reference operator[](size_type n); 
const_reference operator[](size_type n) const; 

trong khi C++14 draft standard có sau đây:

reference operator[](size_type n); 
constexpr const_reference operator[](size_type n) const; 
^^^^^^^^^ 

Cập nhật

Dự thảo tiêu chuẩn N3485 xuất hiện sau C++ 11, có sửa các cải tiến đối với C++ 11. Nó chứa phiên bản constexpr của operator []. Nếu đây là một phần của báo cáo lỗi thì gcc sẽ chính xác và điều này có vẻ hợp lý khi xem xét clang 3.6.0 cũng chấp nhận chương trình ở chế độ C++ 11.

Cập nhật 2

tôi tìm thấy tài liệu mà giới thiệu những thay đổi, N3470 và kể từ khi tôi không thể tìm thấy bất kỳ báo cáo trục trặc về vấn đề cụ thể này thì đây có vẻ như một nâng cao và do đó không phải là một phần của C + +11.

+0

Trong C++ 11, có thể khai báo 'array :: operator [] const' thành' constexpr', nhưng ủy ban không nhận được xung quanh để làm như vậy cho đến khi C++ 14. Trong C++ 14, nó có thể khai báo 'array :: operator []' như 'constexpr' ... – Casey

+1

@Casey Tôi tìm thấy tài liệu đã giới thiệu sự thay đổi thành' N3485', tôi đã thêm nó vào câu trả lời của mình. Theo như tôi hiểu nếu nó được coi là một khiếm khuyết nó nên được cho phép trong chế độ C++ 11 nhưng nếu không thì không. Các tài liệu không làm rõ rằng mặc dù. –

+1

Tôi chủ yếu nói đùa ở tiêu chuẩn: thay đổi thư viện thường tụt hậu so với cốt lõi, bởi vì lõi thích thay đổi vào phút cuối mà không cho thư viện đủ thời gian để phản ứng. Tôi tin rằng bổ sung 'constexpr' trong N3470 là một sự nâng cao, vì báo cáo lỗi duy nhất cho' mảng' liên quan đến 'constexpr' là [LWG DR 720] (http://www.open-std.org/jtc1/sc22 /wg21/docs/lwg-defects.html#720) và không liên quan đến 'toán tử []'. – Casey

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