C++ 这是“const\u cast”的有效用法吗?

C++ 这是“const\u cast”的有效用法吗?,c++,c++11,C++,C++11,C++11标准更改了标准容器的erase()方法的签名:它们现在接受const\u迭代器s,而不是迭代器s。本文件解释了基本原理: 现在,如果以一种简单的方式实现std::vector,则可以直接使用const T*和T*分别作为常量和可变迭代器类型。因此,在erase()方法中,我们可能有如下代码: iterator erase(const_iterator it) { ... for (; it != end() - 1; ++it) { // Destro

C++11标准更改了标准容器的
erase()
方法的签名:它们现在接受
const\u迭代器
s,而不是
迭代器
s。本文件解释了基本原理:

现在,如果以一种简单的方式实现
std::vector
,则可以直接使用
const T*
T*
分别作为常量和可变迭代器类型。因此,在
erase()
方法中,我们可能有如下代码:

iterator erase(const_iterator it)
{
    ...
    for (; it != end() - 1; ++it) {
        // Destroy the current element.
        it->~T();
        // Move-init the current iterator content with the next element.
        ::new (static_cast<void *>(it)) T(std::move(*(it + 1))); // FAIL
    }
    ...
}
迭代器擦除(常量迭代器)
{
...
for(;it!=end()-1;++it){
//销毁当前元素。
它->~T();
//将当前迭代器内容与下一个元素一起移动到init。
::new(static_cast(it))T(std::move(*(it+1));//失败
}
...
}
现在的问题是,由于
it
是一个常量指针,静态强制转换将失败

在这种情况下,将常量从
中丢弃是否合法?请注意,
it
从不指向
const
对象(存储在向量中的对象从不
const
),并且调用方法(
erase()
)也不是
const

编辑:感谢所有回复。我想在这里回应下面的一些评论

此代码来自一个自定义向量类(具有与
std::vector
类似的接口),该类在不受限制的联合上实现了小缓冲区优化。迭代器是裸指针,因为当向量使用静态存储和动态存储时,迭代器的类型必须相同,而这似乎是实现这种结果的最自然的方式


在与统一化存储交互时,对
无效*
的强制转换只是代码库中的习惯和一致性问题。

因为
擦除
是非常量的,所以可以安全地丢弃元素上的常量。但是,请注意,这不是必需的,因为可以从常量迭代器获得非常量迭代器:

iterator non_const = begin() + (it - begin());

这可以用来在向量上迭代。

旁白:我对这个实现有点困惑,您将分解*它,然后用*作为右值传递*(it+1)重新初始化它,这使得*(it+1)处于可分解状态,通常是通过将值从*(it)交换或以成员方式交换到*(it+1)。然后您将析构函数*(it+1),它是空的/从初始的it->~T()中析构函数。似乎您可以在循环之前执行初始析构函数,也可以不用麻烦调用析构函数,这样*(它)基本上被洗牌到容器的末尾,然后在容器丢弃最后一个元素时被销毁。只是想知道为什么要静态强制转换为void*您不应该使用
allocator\u traits
来复制和移动元素,而不是硬编码就地销毁和放置新闻?一个
std::vector
的迭代器类型不应该转换为
void*
@kfsone是的,这是一个好的观点。目前,我并不太关心擦除操作的性能,而是更关注const和nonconst语义。我已经考虑过这一点,但我正试图避免尽可能多的指针差异。在有符号/无符号积分之间来回切换总是让我感到厌烦。@bluescani:在有符号/无符号积分之间没有来回切换。指针减法的结果是有符号类型。当一个整数被添加到指针上时,它将被提升为
std::ptrdiff\u t
。所以这个语句中没有无符号整数。同样,对于标准库迭代器,减法运算的结果类型为
iterator::difference_type
,它始终是有符号类型,通常是
std::ptrdiff_t
的typedef。您能否提供一个参考,说明向指针添加整数值会导致整数值提升?我看的是5.7/5(C++11),它没有说明任何内容。5.7/6提到了关于指针之间差异的ptrdiff\t。@Bluescani:13.6/13显示了指针算术的内置运算符。他们都希望整数是
std::ptrdiff\u t
。谢谢!所以基本上不可能在固定时间内完成足够大的数组的指针积分运算?我还感到惊讶的是,GCC和Clang没有警告潜在的不安全转换,例如,在向指针添加
size\u t
时。。。