为什么std :: array :: size constexpr具有简单类型(int,double,...)而不是std :: vector(GCC)? [英] Why is std::array::size constexpr with simple types (int, double, ...) but not std::vector (GCC)?

查看:118
本文介绍了为什么std :: array :: size constexpr具有简单类型(int,double,...)而不是std :: vector(GCC)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码:

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

...同时使用gccclang进行编译,因为 std::array::size 被认为是constexpr.

...compiles with both gcc and clang because std::array::size is considered constexpr.

但是以下内容无法用gcc编译(版本5.3.0 20151204):

But the following does not compile with gcc (version 5.3.0 20151204):

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

对我来说,如果第一个代码有效,则没有理由使此类代码无法编译,但是由于我没有找到很多相关的文章,所以我不知道这是gcc bug还是扩展?

For me, there is no reason such code should fail to compile if the first one works but since I did not find a lot of post on this I don't know if it is a gcc bug or a clang extension?

gcc中的错误(我不太了解...):

The error from gcc (that I don't really understand... ):

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;
                                                ^

推荐答案

我认为这与 CWG问题1684 有关>.以前,constexpr要求包括:

I think this is a related to CWG issue 1684. Previously, the constexpr requirements included:

constexpr函数为其成员的类应为文字类型

The class of which a constexpr function is a member shall be a literal type

std::array<std::vector<int>, 4>不是 文字类型,因此其size()成员函数将不是constexpr.但是,新的措辞允许非文字类型的constexpr非静态成员函数,前提是这些函数满足constexpr的所有其他要求(array<T,N>::size()显然可以做到).

And std::array<std::vector<int>, 4> is not a literal type, and hence its size() member function would not be constexpr. However, the new wording allows for a constexpr non-static member functions for non-literal types, assuming those functions meet all the other requirements of constexpr (which array<T,N>::size() clearly does).

按照新的措辞,这是一个gcc错误.以前归档为 66297 .

Per the new wording, this is a gcc bug. Previously filed as 66297.

这篇关于为什么std :: array :: size constexpr具有简单类型(int,double,...)而不是std :: vector(GCC)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆