12

当我发现在 C++11 中不能使用元素作为初始化程序时,我正在将一些值填充到 a 中constexpr std::array,然后将编译时静态特性继续添加到更多值中。constexprconstexpr

这是因为std::array::operator[]实际上constexpr直到 C++14 才被标记:https ://stackoverflow.com/a/26741152/688724

编译器标志升级后,我现在可以使用 a 的元素constexpr std::array作为constexpr值:

#include <array>

constexpr std::array<int, 1> array{{3}};
// Initialize a constexpr from an array member through its const operator[]
// that (maybe?) returns a const int & and is constexpr
constexpr int a = array[0];  // Works in >=C++14 but not in C++11

但有时我想在constexpr计算中使用临时数组,但这不起作用。

// Initialize a constexpr from a temporary
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!

我从带有 -std=c++14 的 clang++ 3.6 得到这个:

prog.cc:9:15: error: constexpr variable 'b' must be initialized by a constant expression
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!
              ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:9:19: note: non-constexpr function 'operator[]' cannot be used in a constant expression
constexpr int b = std::array<int, 1>{{3}}[0];  // Doesn't work!
                  ^
/usr/local/libcxx-3.5/include/c++/v1/array:183:41: note: declared here
    _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n)             {return __elems_[__n];}
                                        ^
1 error generated.

我要索引的两个变量之间有什么区别?为什么我不能使用直接初始化的std::array临时operator[]as constexpr

4

3 回答 3

6

第二个示例中的临时变量array本身不是const,因此您最终调用了非const operator[]重载,即不是constexpr。如果您首先arrayconst.

constexpr int b = static_cast<std::array<int, 1> const&>(std::array<int, 1>{{3}})[0];

现场演示

于 2015-07-29T02:16:40.823 回答
4

除了@Praetorian 的解决方法,您可以使用std::get(std::array)

#include<array>
int main(){
    constexpr int b = 
    //  std::array<int, 1>{{3}}[0]; // Doesn't work!
    //  static_cast<std::array<int, 1> const&>(std::array<int, 1>{{3}})[0]; // long but Works!
        std::get<0>(std::array<int, 1>{{3}});// Works!
}

我认为std::getoperator[]制作constexpr.

(使用 C++14 测试clang 3.5gcc 5.0应该使用 C++11)

另外,由于某种原因(与模板参数有关),ADL 在这里不起作用,所以不能只写get<0>(std::array<int, 1>{{3}}).

于 2015-10-13T07:11:55.073 回答
1

我相信您不能使用第二个arrayoperator []因为与第一个不同array,第二个本身不是 aconstexpr所以您尝试b使用运行时值进行初始化。

于 2015-07-29T02:07:35.773 回答