当我发现你不能将一个元素用作{{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
?
答案 0 :(得分:6)
第二个示例中的临时array
本身不是const
,因此您最终会调用非const
operator[]
重载,而不是{{1} }。如果您首先将constexpr
转换为array
,则可以使代码生效。
const
答案 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.5
和gcc 5.0
C ++ 14测试,应该适用于C ++ 11)
另外,由于某些原因(与模板参数有关),ADL在这里不起作用,因此不可能只写get<0>(std::array<int, 1>{{3}})
。
答案 2 :(得分:1)
我相信你不能使用第二个array
的{{1}}因为,与第一个operator []
不同,第二个array
本身不是constexpr
所以你'尝试使用运行时值初始化b
。