为什么 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
.
但以下不编译 gcc
(版本 5.3.0 20151204):
std::array<std::vector<int>, 4> arr1;
std::array<std::vector<double>, arr1.size()> arr2;
对我来说,如果第一个有效,这样的代码没有理由编译失败,但由于我没有找到很多 post,所以我不知道它是否是 gcc
错误或 clang
扩展?
来自 gcc
的错误(我不太明白...):
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 issue 1684 有关。以前,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()
显然满足)。
根据新的措辞,这是一个 gcc 错误。以前归档为 66297.
以下代码:
std::array<int, 4> arr1;
std::array<float, arr1.size()> arr2;
...用 gcc
和 clang
编译,因为 std::array::size
被认为是 constexpr
.
但以下不编译 gcc
(版本 5.3.0 20151204):
std::array<std::vector<int>, 4> arr1;
std::array<std::vector<double>, arr1.size()> arr2;
对我来说,如果第一个有效,这样的代码没有理由编译失败,但由于我没有找到很多 post,所以我不知道它是否是 gcc
错误或 clang
扩展?
来自 gcc
的错误(我不太明白...):
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 issue 1684 有关。以前,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()
显然满足)。
根据新的措辞,这是一个 gcc 错误。以前归档为 66297.