繁体   English   中英

constexpr数组和std :: initializer_list

[英]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构造函数, beginsize都很好,即使它严格来说不是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和成员函数的beginend都没有标记为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM