为什么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)?
问题描述
以下代码:
std::array<int, 4> arr1;
std::array<float, arr1.size()> arr2;
...同时使用gcc
和clang
进行编译,因为 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屋!