
[英]Validation of an std::initializer_list in constexpr context
[英]constexpr array and std::initializer_list
我试图编写一个可以像这样使用的编译时valarray:
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
static_assert(a[0] == 1.0, "");
static_assert(a[3] == 4.3, "");
static_assert(a.size() == 6, "");
我设法用以下实现来做它并且它工作正常(使用GCC 4.7):
#include <initializer_list>
template<typename T>
struct array
{
private:
const std::size_t _size;
const T* _data;
public:
constexpr array(std::initializer_list<T> values):
_size(values.size()),
_data(values.begin())
{}
constexpr auto operator[](std::size_t n)
-> T
{
return _data[n]
}
constexpr auto size() const
-> std::size_t;
{
return _size;
}
};
虽然它对我来说很好,但我不确定std::initializer_list
的行为,可能会使用一些未定义的行为。
constexpr
for std::initializer_list
构造函数, begin
和size
都很好,即使它严格来说不是C ++ 11,因为N3471最近被采用并使其符合标准。
关于未定义的行为,我不确定std::initializer_list
的底层数组是否存在,或者是否存在,是否有一个意思是让它比只有array's
构造函数更长寿。 你怎么看?
编辑:我可能不太清楚,但我真的不关心实际的阵列。 我真正感兴趣的是std::initializer_list
及其在编译时的底层数组的行为。
您当前的代码不应该根据当前的C ++ 11规则进行编译 。 使用clang 3.2编译时,我收到以下错误:
source.cpp:33:28: error: constexpr variable 'a' must be initialized by a constant
expression
constexpr array<double> a = { 1.0, 2.1, 3.2, 4.3, 5.4, 6.5 };
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这是因为std::initializer_list
s ctors和成员函数的begin
和end
都没有标记为constexpr
。 但是, 已经提出了改变这一点的建议 。 顺便说一句,libstdc ++已经将这些标记为constexpr
。
现在下一个问题是std::initializer_list
的底层数组的生命周期 。 这在8.5.4p6中解释:
该数组与任何其他临时对象(12.2)具有相同的生命周期,除了从数组初始化initializer_list对象扩展了数组的生命周期,就像绑定对临时对象的引用一样。
这意味着底层数组与values
对象具有相同的生命周期,并在array
构造函数退出时终止。 因此, _data
指向过期的内存, _data[n]
是未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.