c++ - 自 C++20 以来是否允许对分配的存储进行指针运算?
问题描述
在 C++20 标准中,据说数组类型是隐式生命周期类型。
这是否意味着可以隐式创建非隐式生命周期类型的数组?这样一个数组的隐式创建不会导致数组元素的创建?
考虑这种情况:
//implicit creation of an array of std::string
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (which object?)
std::string * sptr = std::launder(static_cast<std::string*>(ptr));
//pointer arithmetic on not created array elements well defined?
new (sptr+1) std::string("second element");
自 C++20 以来,此代码不再是 UB 了吗?
也许这种方式更好?
//implicit creation of an array of std::string
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//use launder to get a "pointer to object" (actually not necessary)
std::string (* sptr)[10] = std::launder(static_cast<std::string(*)[10]>(ptr));
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");
TC 答案 + 评论结论:
- 未创建数组元素,但已创建数组
- 在第一个示例中使用
launder
导致 UB,在第二个示例中没有必要。
正确的代码是:
//implicit creation of an array of std::string
//but not the std::string elements:
void * ptr = operator new(sizeof (std::string) * 10);
//the pointer already points to the implicitly created object
//so casting is enough
std::string (* sptr)[10] = static_cast<std::string(*)[10]>(ptr);
//pointer arithmetic on an array is well defined
new (*sptr+1) std::string("second element");
解决方案
这是否意味着可以隐式创建非隐式生命周期类型的数组?
是的。
这样一个数组的隐式创建不会导致数组元素的创建?
是的。
这就是std::vector
在普通 C++ 中可以实现的原因。
推荐阅读
- python - Python Spark用flatMap爆炸替换
- python - 在python中以相同的单位制作数字浮点数
- google-cloud-firestore - 使用firestore作为数据库时如何从datagridview中搜索值
- r - 使用R从具有字符串和数字数据的变量中提取数字
- reactjs - Formik onChange 执行但不更改字段值?
- css - 更改工具提示 CSS bootstrap 4 的样式
- html - 如何将中心的文本与 SVG 元素对齐?
- html - 扩展菜单区域内输入框的悬停区域
- angular - 访问 div 外的 ngform 时出现错误 TS2339
- ios - 使用 Combine 框架向 UIViewController 添加分页以实现无限滚动