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

时间:2015-06-11 03:17:05

标签: c++ c++11

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和mutable迭代器类型。所以在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是一个const指针,静态强制转换将失败。

在这种情况下从it抛弃常量是否合法?请注意,it从不指向const对象(存储在向量中的对象永远不会const),并且调用方法(erase())不是{{1同样。

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

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

在与单一化存储交互时,转换为std::vector只是代码库中习惯和一致性的问题。

1 个答案:

答案 0 :(得分:6)

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

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

这可以用来迭代向量。