#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;
}
使用gcc 4.8.2
编译4.9.1
和g++ test.cpp --std=c++11
时,编译成功。
使用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
所以我的问题是,在符合C ++ 11的意义上,哪个编译器是“正确的”?并且,如果clang
是正确的,那么为什么std :: array的operator[]
不具备constexpr能力?这不是std::array
应该帮助解决的事情之一吗?
答案 0 :(得分:9)
看起来clang
是正确的,operator []不是C ++ 11中的constexpr,而是C ++ 14中的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的增强功能。它包含{em> constexpr 版本的operator []
。如果这是缺陷报告的一部分,那么gcc
将是正确的,这似乎是合理的,因为clang 3.6.0
也接受C ++ 11模式的程序。
更新2
我找到了引入更改的文档N3470,因为我找不到关于这个特定问题的任何缺陷报告,所以这似乎是一个增强,因此不应该是C ++ 11的一部分。