简体   繁体   English

这是``const_cast``的有效用法吗?

[英]Is this a valid usage of ``const_cast``?

The C++11 standard has changed the signature of the erase() methods of standard containers: they now accept const_iterator s instead of iterator s. C ++ 11标准改变了标准容器的erase()方法的签名:它们现在接受const_iterator而不是iterator s。 The rationale is explained in this document: 本文档解释了该基本原理:

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

Now, if one implements std::vector<T> in a straightforward way, it is possible to use directly const T * and T * as const and mutable iterator types respectively. 现在,如果以简单的方式实现std::vector<T> ,则可以直接使用const T *T *作为const和可变迭代器类型。 So in the erase() method we might have code like this: 所以在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
    }
    ...
}

The problem now is that, since it is a const pointer, the static cast will fail. 现在的问题是,由于it是一个const指针,静态强制转换将失败。

Is it legal in this case to cast away the constness from it ? 它是法律在这种情况下,从抛弃常量性it Note that it never points to a const object (the objects stored in the vector are never const ), and that the calling method ( erase() ) is not const as well. 请注意, it永远不会指向const对象(存储在向量中的对象永远不会是const ),并且调用方法( erase() )也不是const

EDIT : thanks for all the replies. 编辑 :感谢所有的回复。 I wanted to respond here to some comments below. 我想在这里回复一些评论。

This code comes from a custom vector class (with a similar interface to std::vector ) that implements the small buffer optimisation on top of an unrestricted union. 此代码来自自定义向量类(具有与std::vector类似的接口),它在无限制联合之上实现小缓冲区优化。 The iterators are naked pointers because they need to be the same type both when the vector is using static storage and when it is using dynamic storage, and this seems the most natural way of achieving such result. 迭代器是裸指针,因为它们在向量使用静态存储时和使用动态存储时都需要是相同的类型,这似乎是实现这种结果的最自然的方式。

The cast to void * is just a matter of habit and consistency within the codebase when interacting with unitialised storage. 在与单元化存储交互时,转换为void *只是代码库中习惯和一致性的问题。

Since erase is non-const, yes, you can safely cast away const on the element. 由于erase是非const的,是的,你可以安全地抛弃元素上的const。 However, note that this is not necessary, since a non-const iterator can be obtained from the const iterator: 但是,请注意,这不是必需的,因为可以从const迭代器获取非const迭代器:

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

And that can be used to iterate over the vector. 这可以用来迭代向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM