AnA*_*ons 10 c++ arrays constexpr c++14 c++17
例如,如果我们有一个std::array并且我们使用constexpr编译器实例化一个超出绑定的元素将不会报告错误:
constexpr int EvaluateSpecialArrayIndex(int a)
{ return a * sizeof(int); }
array<int, 5> arr;
cout << arr[98] << endl; //compiles fine
cout << arr[EvaluateSpecialArrayIndex(4)] << endl; //the same as above
Run Code Online (Sandbox Code Playgroud)
我们不能以某种方式限制这个吗?
How*_*ant 13
要确保constexpr在编译时评估函数,必须通过生成结果强制它们constexpr.例如:
#include <array>
int
main()
{
constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
int i = arr[6]; // run time error
}
Run Code Online (Sandbox Code Playgroud)
然而:
#include <array>
int
main()
{
constexpr std::array<int, 5> arr{1, 2, 3, 4, 5};
constexpr int i = arr[6]; // compile time error
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,为了实际工作,std::array必须符合C++ 14规范,而不是C++ 11规范.由于C++ 11规范没有标记with 的const重载.std::array::operator[]constexpr
所以在C++ 11中你运气不好.在C++ 14中,您可以使它工作,但array前提是同时声明了调用索引运算符的结果和结果constexpr.
澄清
用于数组索引的C++ 11规范读取:
reference operator[](size_type n);
const_reference operator[](size_type n) const;
Run Code Online (Sandbox Code Playgroud)
并且用于数组索引的C++ 14规范读取:
reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
Run Code Online (Sandbox Code Playgroud)
即constexpr加入到const过载用于C++ 14.
更新
并且用于数组索引的C++ 17规范读取:
constexpr reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;
Run Code Online (Sandbox Code Playgroud)
周期现已完成.可以在编译时计算Universe.;-)
如果您在编译时知道数组索引,则可以使用std::get索引,如果超出范围,将导致编译失败
std::array<int, 4> a{{1,2,3,4}};
std::get<4>(a); // out of bounds, fails to compile
Run Code Online (Sandbox Code Playgroud)
我从gcc-4.9得到的错误以:
error: static assertion failed: index is out of bounds
static_assert(_Int < _Nm, "index is out of bounds");
Run Code Online (Sandbox Code Playgroud)
std::get仅适用于常量表达式索引(索引是模板参数),因此使用std::array它始终可以在编译时检测越界.
std::array对于常规C数组,a 上的数组访问是相同的,它从不检查索引是否有效,如果它超出范围,它只调用UB.如果需要限制,请使用为超出数组边界的值std::array::at()抛出std::out_of_range()异常.
arr.at(EvaluateSpecialArrayIndex(4)); // terminate called after throwing
// an instance of 'std::out_of_range'
Run Code Online (Sandbox Code Playgroud)
如果您想要编译时错误,请使用std::get:
std::get<EvaluateSpecialArrayIndex(4)>(arr); // error: static_assert failed
// "index is out of bounds"
Run Code Online (Sandbox Code Playgroud)