2016-04-14 15 views
16

Các mã sau đây:Tại sao std :: array :: size constexpr với các kiểu đơn giản (int, double, ...) nhưng không std :: vector (GCC)?

std::array<int, 4> arr1; 
std::array<float, arr1.size()> arr2; 

... biên dịch với cả gccclangstd::array::size được coi constexpr.

Nhưng sau không biên dịch với gcc (phiên bản 5.3.0 20.151.204):

std::array<std::vector<int>, 4> arr1; 
std::array<std::vector<double>, arr1.size()> arr2; 

Đối với tôi, không có lý do mã như vậy nên không biên dịch nếu là người đầu tiên hoạt động nhưng kể từ khi tôi đã không tìm thấy rất nhiều bài viết về điều này tôi không biết nếu nó là một lỗi gcc hoặc một phần mở rộng clang?

Các lỗi từ gcc (mà tôi không thực sự hiểu ...):

main.cpp: In function 'int main()': 
main.cpp:6:46: error: call to non-constexpr function 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' 
    std::array<std::vector<double>, arr1.size()> arr2; 
              ^
In file included from main.cpp:1:0: 
/usr/local/include/c++/5.3.0/array:170:7: note: 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' is not usable as a constexpr function because: 
     size() const noexcept { return _Nm; } 
    ^
/usr/local/include/c++/5.3.0/array:170:7: error: enclosing class of constexpr non-static member function 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' is not a literal type 
/usr/local/include/c++/5.3.0/array:89:12: note: 'std::array<std::vector<int>, 4ul>' is not literal because: 
    struct array 
      ^
/usr/local/include/c++/5.3.0/array:89:12: note: 'std::array<std::vector<int>, 4ul>' has a non-trivial destructor 
main.cpp:6:46: error: call to non-constexpr function 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' 
    std::array<std::vector<double>, arr1.size()> arr2; 
              ^
main.cpp:6:48: note: in template argument for type 'long unsigned int' 
    std::array<std::vector<double>, arr1.size()> arr2; 
               ^
+1

Thú vị là MSVS2015 và kêu gọi cả hai biên dịch. MSVS intellisense không thích nó nhưng nó được chấp nhận bởi trình biên dịch. – NathanOliver

+1

Có 'tuple_size > :: giá trị' nếu bạn cần giải pháp: / – melak47

Trả lời

21

Tôi nghĩ rằng đây là một liên quan đến CWG issue 1684. Trước đó, các yêu cầu constexpr bao gồm:

Lớp trong đó một hàm constexpr là thành viên có trách nhiệm là một loại đen

std::array<std::vector<int>, 4>không một loại đen, và do đó chức năng size() thành viên sẽ không là constexpr. Tuy nhiên, từ ngữ mới cho phép một hàm thành viên không tĩnh constexpr đối với các loại không theo nghĩa đen, giả sử các hàm đó đáp ứng tất cả các yêu cầu khác của constexpr (trong đó array<T,N>::size() rõ ràng).

Mỗi từ ngữ mới, đây là lỗi gcc. Đã nộp trước đây là 66297.

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