在考虑问题std::initializer list from already existing std::array without enumerating each element的解决方案时,我开发了与bolov类似的机制,但没有构建对象,而只是初始化列表。我很惊讶我的解决方案不起作用,我无法弄清楚原因。
#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
的值。
答案 0 :(得分:1)
通过程序集here(clang 4.0.0)和/或here(GCC 7.1),显然std::initializer_list
正在使用悬空指针,我们都知道)产生看似随机的输出。
修改强>
此结果当然与Igor Tandetnik引用的评论一致,引用cppreference.com:
底层数组是const T [N]类型的临时数组,其中每个元素都是从原始初始化列表的相应元素进行复制初始化(除了缩小转换无效)。底层数组的生命周期与任何其他临时对象相同,除了从数组初始化initializer_list对象扩展了数组的生命周期,就像绑定对临时的引用一样(具有相同的例外,例如初始化非 - 静态班级成员)。底层数组可以在只读存储器中分配。
答案 1 :(得分:1)
[dcl.init.list] / 5 类型为
std::initializer_list<E>
的对象是从初始化列表构造的,就好像实现分配了N
个元素类型的数组一样E
,其中N
是初始值设定项列表中的元素数。使用初始化列表的相应元素对该数组的每个元素进行复制初始化,并构造std::initializer_list<E>
对象以引用该数组。[dcl.init.list] / 6 数组的生命周期与
initializer_list
对象的生命周期相同。
最后一部分对您的示例非常重要。 array_to_init_list_helper
返回原始initializer_list
的副本 - 但基础数组的生命周期以原始数据的生命周期结束。副本指的是其生命周期已经结束的对象。然后,您的程序会显示未定义的行为。