这是“const_cast”的有效用法吗?
Is this a valid usage of ``const_cast``?
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());
这可以用来迭代向量。
相关文章:
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 这个指针在c++中的用法
- 有效地使用std::unordered_map来插入或增加键的值
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 当C++中需要自动删除时,这是静态的正确用法吗?
- 为什么这种直接初始化有效?(C++17)
- 递归函数有效,但无法记忆
- 在C++中初始化向量映射的最有效方法
- libstdc++ 文件系统中未初始化的用法?
- reinterpret_cast<char *> 是reinterpret_cast的唯一有效用法吗?
- std::vector<decltype(iter)>-decltype的有效用法
- 这是“const_cast”的有效用法吗?