这是“const_cast”的有效用法吗?

Is this a valid usage of ``const_cast``?

本文关键字:有效 用法 const cast 这是      更新时间:2023-10-16

C++11标准改变了标准容器erase()方法的签名:它们现在接受const_iterator而不是iterator s。本文档解释了基本原理:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2350.pdf

现在,如果以直接的方式实现std::vector<T>,则可以直接使用 const T *T * 分别作为 const 和可变迭代器类型。因此,在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
    }
    ...
}

现在的问题是,由于it是一个常量指针,静态强制转换将失败。

在这种情况下,抛弃it的恒定性是否合法?注意it从不指向const对象(存储在向量中的对象永远不会const),调用方法(erase())也不const

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

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

转换

void *只是与单元化存储交互时代码库中的习惯和一致性问题。

由于erase是非常量,是的,您可以安全地丢弃元素上的常量。但是,请注意,这不是必需的,因为可以从常量迭代器获取非常量迭代器:

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

这可以用来迭代向量。