10
#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.24.9.1using编译时g++ test.cpp --std=c++11,编译成功。然而,当编译clang 3.43.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::arrayoperator[]不能使用 constexpr?这不是std::array应该帮助解决的事情之一吗?

4

1 回答 1

9

看起来clang是正确的,运算符 []不是 C++11 中的 constexpr,而是 C++14 中的 constexpr

constexpr const_reference operator[]( size_type pos ) const; (since C++14)

所以编译-std=c++14应该可以工作(现场查看)。

C++11 草案标准部分中,23.3.2.1 类模板数组概述具有以下内容operator []

reference operator[](size_type n);
const_reference operator[](size_type n) const;

C++14 草案标准具有以下内容:

reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
^^^^^^^^^

更新

C++11 之后的标准草案N3485包含对 C++11 的增强。它包含一个constexpr版本operator []。如果这是缺陷报告的一部分,那么这是正确的,考虑到也接受 C++11 模式下的程序,gcc这似乎是合理的。clang 3.6.0

更新 2

我找到了介绍更改的文档N3470 ,由于我找不到有关此特定问题的任何缺陷报告,因此这似乎是一种增强,因此不应成为 C++11 的一部分。

于 2014-11-04T17:18:13.003 回答