constexpr数组和std :: initializer_list [英] constexpr array and std::initializer_list

查看:182
本文介绍了constexpr数组和std :: initializer_list的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一个编译时valarray,可以这样使用:

I was trying to write an compile-time valarray that could be used like this:

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) p>

I managed to do it with the following implementation and it works fine (with 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 并且可能使用一些未定义的行为。

Even though it works fine for me, I am not sure about the behaviour of std::initializer_list and may use some that are undefined behaviour.

constexpr std :: initializer_list 构造函数, begin size 精细即使不严格说来是C ++ 11,因为N3471最近被采用,并使其达到标准。

constexpr for std::initializer_list constructor, begin and size is fine even though it is not strictly speaking C++11 since N3471 recently got adopted and made it to the standard.

关于未定义的行为,我不知道 std :: initializer_list 的底层数组将会存活,如果没有,是否有一个平均值它只活动数组的构造函数。

Concerning the undefined behaviour, I am not sure whether the underlying array of the std::initializer_list will live or if not, whether there is a mean to have it live longer than only array's constructor. What do you think?

编辑:我可能不太清楚,但我真的不在乎实际的数组。真正感兴趣的是在编译时 std :: initializer_list 及其底层数组的行为。

I may not have been clear, but I do not really care about the actual array. What really interests me is the behaviour of std::initializer_list and its underlying array at compile-time.

推荐答案

根据当前C ++ 11规则,您当前的代码不应该编译。当使用clang 3.2编译时,我收到以下错误:

Your current code should not compile according to current C++11 rules. When compiled with clang 3.2 I get the following error:

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 的ctors和成员函数 begin end 未标记为 constexpr 。但是,已有建议更改此。 BTW,libstdc ++已经标记为 constexpr

This is because std::initializer_lists ctors and member functions begin and end are not labeled constexpr. However, there already is a proposal to change this. BTW, libstdc++ already marks these as constexpr.

现在下一个问题是 lifetime std :: initializer_list 的底层数组。这在8.5.4p6中解释:

Now the next problem is the lifetime of the underlying array of std::initializer_list. This is explained in 8.5.4p6:


数组与任何其他临时对象(12.2),
从数组
初始化initializer_list对象就像绑定一个对
a临时的引用一样延长数组的生命周期。

The array has the same lifetime as any other temporary object (12.2), except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary.

这意味着底层数组与 values 对象具有相同的生命周期,并且在数组的末尾过期构造函数退出时。因此, _data 指向过期内存, _data [n] 是未定义的行为。

This means that the underlying array has the same lifetime as values object, and expires at the end of your array constructor when it exits. Therefore, _data is pointing to expired memory and _data[n] is undefined behavior.

这篇关于constexpr数组和std :: initializer_list的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆