我想将可变参数类型列表“物化”为相关值的initializer_list。
例如,具有多个std::tuple
的{{1}}得到一个std::integral_constant<T, x>
。
通常,我想获取一些复杂类型的initializer_list,例如std::initializer_list<T>{...}
。
但是下面的简单示例让我在用Clang编译时崩溃了(尽管它与GCC兼容,至少在Coliru上有效),所以我怀疑UB(或Clang中的错误):
std::string
那么,这样的代码合法吗?在C ++ 11/14/17中?
答案 0 :(得分:9)
关于initializer_list的两件事:
初始化程序列表可以实现为一对指针或指针 和长度。复制std :: initializer_list 不复制 基础对象。
和
不能保证基础数组在存在之后就存在 原始的初始化程序列表对象已结束。的存储 std :: initializer_list未指定(即可以是自动的, 临时或静态只读存储器,具体取决于情况)。
所以在这一行
return {
std::to_string(Ts::value)...
};
您正在创建本地数组,initializer_list保持指向该数组的开始/结尾的指针,当函数超出范围时,您将拥有悬空的指针。
答案 1 :(得分:3)
std::initializer_list
的基础数组实际上是一个本地临时对象。当离开<input type="hidden" name="certid" value="<?php print base64_encode(serialize($result)); ?>">
时,它已被破坏。复制$data = unserialize(base64_decode($this->input->post('certid')));
不会复制基础数组,返回的materialize
的内容始终无效,尝试访问返回的std::initializer_list
的内容会导致UB。
(重点是我的)
初始化程序列表可以实现为一对指针或指针 和长度。 复制std :: initializer_list不会复制 基础对象。
基础数组是类型为
std::initializer_list
的临时数组,位于 每个元素都被复制初始化(缩小范围除外) 转换无效) 原始的初始化程序列表。基础数组的生命周期是 与其他任何临时对象相同,除了初始化 数组中的initializer_list对象延长了 数组完全类似于将引用绑定到临时(具有相同的 异常,例如用于初始化非静态类成员的异常)。的 基础数组可以分配在只读内存中。