#include <iostream> #include <array> int main(int argc,char **argv) { constexpr const std::array<int,2> arr {{ 0,1 }}; constexpr const int arr2[] = { 0,1}; static_assert(arr[0] == arr2[0],"asdf"); static_assert(arr[1] == arr2[1],"asdfasdf"); return 0; }
当使用g test.cpp –std = c 11编译gcc 4.8.2和4.9.1时,编译成功.
然而,当使用clang 3.4和3.5编译时,使用clang test.cpp –std = c 11,编译失败:
test.cpp:8:16: error: static_assert expression is not an integral constant expression static_assert(arr[0] == arr2[0],"asdf"); ^~~~~~~~~~~~~~~~~ test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used in a constant expression
所以我的问题是,哪个编译器在符合C11的意义上是“正确的”?而且,如果clang是正确的,那么为什么std :: array的operator []不是constexpr能力?这不是std :: array应该帮助解决的一件事吗?
解决方法
看起来cl声是正确的,operator []不是C11中的constexpr,而是C14中的constexpr
constexpr const_reference operator[]( size_type pos ) const; (since C++14)
所以用-std = c 14编译应该可以(see it live).
在C++11 draft standard部分23.3.2.1类模板阵列概述对于operator []有以下内容:
reference operator[](size_type n); const_reference operator[](size_type n) const;
而C++14 draft standard则具有以下特点:
reference operator[](size_type n); constexpr const_reference operator[](size_type n) const; ^^^^^^^^^
更新
C 11之后的标准N3485草案包含修复对C 11的增强.它包含一个constexpr版本的operator [].如果这是缺陷报告的一部分,那么gcc将是正确的,这似乎是合理的考虑到cl ang 3.6.0也接受程序在C 11模式.
更新2
我发现引入变化的文档,N3470,因为我没有找到关于这个具体问题的缺陷报告,那么这似乎是一个增强,因此不应该是C11的一部分.