提问人:jdehesa 提问时间:9/22/2023 最后编辑:Jan Schultkejdehesa 更新时间:9/23/2023 访问量:63
将unique_ptr的矢量数据转换为指向常量指针
Cast vector data of unique_ptr to pointer to const pointer
问:
我有一个 of,我想从 API 调用一个函数,该函数将指针指向 const 指针。将其转换为该类型是否正确?std::vector
std::unique_ptr
data()
这个示例程序似乎在 GCC 中工作:
#include <vector>
#include <iostream>
#include <memory>
class A
{
public:
A(int n) : n(n) {}
int n;
};
int main()
{
const int num = 3;
std::vector<std::unique_ptr<A>> v;
for (int i = 0; i < num; i++)
{
v.push_back(std::make_unique<A>(i));
}
auto vPtr = (A * const *) v.data();
for (int i = 0; i < num; i++)
{
std::cout << vPtr[i]->n << std::endl;
}
return 0;
}
标准是否保证布局只是一个指针,因此这样做是安全的?std::unique_ptr
答:
3赞
Caleth
9/22/2023
#1
不,这是别名冲突。A 不是原始指针。std::unique_ptr
“似乎在 GCC 中有效”在 C++ 中并不安全。你的代码有未定义的行为,“似乎有效”是最糟糕的症状,因为它可能会在没有通知的情况下突然变成“以最不合时宜的方式中断”。
评论
0赞
Jan Schultke
9/23/2023
OP 的代码可以定义明确,但假设是标准布局。标准不保证这一点,因此这不是安全的假设,但称其为没有星号的严格混叠违规也是不正确的。std::unique_ptr
0赞
Caleth
9/23/2023
@JanSchultke您仍然必须尊重演员的混叠,但这里的情况并非如此,我们正在添加const
0赞
Jan Schultke
9/23/2023
C 样式的演员也可以充当 ,所以这很好。由于 const-correctness,不允许在此处隐式添加,但允许通过强制转换这样做。无论如何,const 对 OP 的代码没有任何影响,也不会使它或多或少成为 UB。这一切都归结为是否是标准布局。const_cast
const
std::unique_ptr
0赞
Caleth
9/23/2023
标准布局允许您在不违反锯齿的情况下进行,但它不会让您在不违反锯齿的情况下进行reinterpret_cast
const_cast
1赞
Caleth
9/24/2023
@JanSchultke添加 const 与严格别名并非无关。这是次要的,也假设这是标准布局std::unique_ptr
评论
v[i].get()
std::unique_ptr
的布局只是一个指针?”不是全部。不要忘记,唯一指针具有 deleter 子对象。即使无状态删除程序可以优化为不占用存储空间,但这并不能保证。shadow.reserve(v.size())