为啥 std::array::size constexpr 具有简单类型(int,double,...)而不是 std::vector (GCC)?
Posted
技术标签:
【中文标题】为啥 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::size constexpr 具有简单类型(int,double,...)而不是 std::vector (GCC)? 【发布时间】:2016-04-14 12:37:07 【问题描述】:以下代码:
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;
对我来说,如果第一个代码有效,那么没有理由编译失败,但由于我没有找到很多关于此的帖子,我不知道它是 gcc
错误还是 @987654330 @扩展?
来自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;
^
【问题讨论】:
有趣的是 MSVS2015 和 clang 都可以编译。 MSVS intellisense 不喜欢它但被编译器接受。 如果您需要解决方法,可以使用tuple_size<array<T,N>>::value
:/
【参考方案1】:
我认为这与CWG issue 1684 有关。以前,constexpr
要求包括:
constexpr
函数所属的类应为文字类型
而std::array<std::vector<int>, 4>
不是文字类型,因此它的size()
成员函数不会是constexpr
。然而,新的措辞允许非文字类型的constexpr
非静态成员函数,假设这些函数满足constexpr
的所有其他要求(array<T,N>::size()
显然满足)。
根据新的措辞,这是一个 gcc 错误。之前提交为66297。
【讨论】:
以上是关于为啥 std::array::size constexpr 具有简单类型(int,double,...)而不是 std::vector (GCC)?的主要内容,如果未能解决你的问题,请参考以下文章
为啥要设计一个库来在 Javascript 中使用 const [] 而不是 const ?
为啥非 const 方法是私有的时不调用公共 const 方法?