c++ - 修改 std::set 的元素 - 定义的行为?

标签 c++ set const-cast

给定以下代码:

#include <set>

struct X {
    int a, b;
    friend bool operator<(X const& lhs, X const& rhs) {
        return lhs.a < rhs.a;
    }
};

int main() {
    std::set<X> xs;
    // some insertion...
    auto it = xs.find({0, 0}); // assume it != xs.end()

    const_cast<X&>(*it).b = 4; // (1)
}

(1) 是否定义了行为?即,我是否允许 const_cast 对从 std::setconst_iterator 获取的元素的引用,并在修改完成时修改它不改变顺序?

我在这里和那里阅读了一些提出这种 const_cast 的帖子,但我想知道这是否是实际定义的行为。

最佳答案

这是否定义了行为尚不清楚,但我相信是的。

std::set的描述中似乎没有具体禁止。关于修改值,除了您已经暗示的限制外,比较器在传递相同的输入时必须返回相同的结果 ([associative.reqmts]p3)。

但是,修改对象的一般规则定义为 const确实适用。是否set将其元素定义为 const没有拼写出来。如果是,则不允许修改元素 ([dcl.type.cv]p4)。

但是 [container.requirements.general]p3 显示:

For the components affected by this subclause that declare an allocator_type, objects stored in these components shall be constructed using the allocator_traits<allocator_type>::construct function and destroyed using the allocator_traits<allocator_type>::destroy function (20.7.8.2).

std::set<T>声明一个 allocator_type , 默认为 std::allocator<T> . std::allocator_traits<allocator_type>::construct将它传递给 T * ,导致 T要构建,而不是 const T .

我相信这意味着 std::set<T>不允许将其元素定义为 const ,并且由于没有任何其他禁止,意味着通过 const_cast 修改元素是允许的。


就我个人而言,如果我找不到更好的选择,我会考虑通过将整个东西放在一个包装器结构中来避免这个问题,它定义了一个成员 mutable X x; .这将允许在没有 const_cast 的情况下进行修改,只要您注意避免更改集合中已有元素的相对顺序即可。它还可以作为您的代码的其他读者的文档,说明您的集合的元素可以并且将会被修改。

关于c++ - 修改 std::set 的元素 - 定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43340050/

相关文章:

java - 如何将 UnmodifyingSet 中的所有值添加到 ArrayList 中?

c++ - 当你用 const_cast 移除 const 时,什么时候可以修改一个值?

c++ - 是否可以在数组上使用 const_cast 来更改元素?

c++ - 如何复制directshow的SampleCB中的示例数据?

c++ - Makefile 第一个规则目标

image - 如何设置asp.net图像控件的宽度和高度属性

c++ - 复制构造函数和带有std::any的构造函数之间的冲突

c++ - 如何在 C++ 中创建零元仿函数(使用 loki 库)

python - NLTK 替换停用词