为什么不是std :: array临时constexpr的operator []?

时间:2015-07-29 01:51:52

标签: c++ c++11 c++14 constexpr stdarray

当我发现你不能将一个元素用作{{1}时,我将一些值填充到constexpr中,然后将编译时静态良好值继续为更多constexpr值。 C ++ 11中的初始化程序。

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

编译器标志升级后,我现在可以使用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!

我从clang ++ 3.6获得了这个-std = c ++ 14:

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[]作为constexpr

3 个答案:

答案 0 :(得分:6)

第二个示例中的临时array本身不是const,因此您最终会调用非const operator[]重载,而不是{{1} }。如果您首先将constexpr转换为array,则可以使代码生效。

const

Live demo

答案 1 :(得分:3)

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

#include<array>
int main(){
    constexpr int b = 
    //  std::array<int, 1>http://quickblox.com/developers/SimpleSample-chat_users-ios#Chat_in_1-1_private_dialog[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::get更具侵略性&#34;产生operator[]时的constexpr

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

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

答案 2 :(得分:1)

我相信你不能使用第二个array的{​​{1}}因为,与第一个operator []不同,第二个array本身不是constexpr所以你'尝试使用运行时值初始化b