通过枚举值构造initializer_list包含随机值

Constructing initializer_list by enumerating values contains random values

虽然考虑了问题 , I developed similar mechanism as 的解决方案,但没有构建对象,而只是初始化列表。我很惊讶我的解决方案不起作用,我也不知道为什么。

#include <initializer_list>
#include <iostream>
#include <array>

template<typename T, std::size_t N, std::size_t... Is>
std::initializer_list<T> array_to_init_list_helper(std::array<T, N> arr, std::index_sequence<Is...>)
{
    return {arr[Is]...};
}

template<typename T, std::size_t N>
std::initializer_list<T> array_to_init_list(std::array<T, N> arr)
{
    return array_to_init_list_helper(arr, std::make_index_sequence<N>{});
}

int main()
{
    std::array<int, 5> arr{1, 2, 3, 4, 5};
    auto init_list = array_to_init_list(arr);
    for (auto val : init_list)
        std::cout << val << " ";
}

我是 getting random values,而我希望获得 arr 的值。

通过程序集 here (clang 4.0.0) and/or here (GCC 7.1),很明显 std::initializer_list 使用了一个悬挂指针,它(众所周知)产生看似随机的输出。

编辑

这个结果当然符合Igor Tandetnik, quoting cppreference.com的评论:

The underlying array is a temporary array of type const T[N], in which each element is copy-initialized (except that narrowing conversions are invalid) from the corresponding element of the original initializer list. The lifetime of the underlying array is the same as any other temporary object, except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary (with the same exceptions, such as for initializing a non-static class member). The underlying array may be allocated in read-only memory.

[dcl.init.list]/5 An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated an array of N elements of type E, where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list<E> object is constructed to refer to that array.

[dcl.init.list]/6 The lifetime of the array is the same as that of the initializer_list object.

这最后一部分对您的示例很重要。 array_to_init_list_helper returns 原始数组的副本 initializer_list - 但底层数组的生命周期以原始数组的生命周期结束。副本指的是生命周期已经结束的对象。然后您的程序表现出未定义的行为。