使用 mutable 允许修改 unordered_set 中的对象 [英] Using mutable to allow modification of object in unordered_set

查看:54
本文介绍了使用 mutable 允许修改 unordered_set 中的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

#include <iostream>
#include <unordered_set>

struct MyStruct
{
    int x, y;
    double mutable z;

    MyStruct(int x, int y)
        : x{ x }, y{ y }, z{ 0.0 }
    {
    }
};

struct MyStructHash
{
    inline size_t operator()(MyStruct const &s) const
    {
        size_t ret = s.x;
        ret *= 2654435761U;
        return ret ^ s.y;
    }
};

struct MyStructEqual
{
    inline bool operator()(MyStruct const &s1, MyStruct const &s2) const
    {
        return s1.x == s2.x && s1.y == s2.y;
    }
};

int main()
{
    std::unordered_set<MyStruct, MyStructHash, MyStructEqual> set;
    auto pair = set.emplace(100, 200);

    if (pair.second)
        pair.first->z = 300.0;

    std::cout << set.begin()->z;
}

我正在使用 mutable 来允许修改 MyStruct 的成员 z.我想知道这是否正常和合法,因为集合是 a) 无序和 b) 我没有使用 z 进行散列或相等?

I am using mutable to allow modification of the member z of MyStruct. I would like to know if this is ok and legal, since the set is a) unordered and b) I am not using z for hashing or equality?

推荐答案

我想说这是对可变"关键字的完美使用.

I would say this is a perfect use of the "Mutable" keyword.

mutable 关键字用于标记不属于类状态"的成员(即它们是某种形式的缓存或中间值,不代表对象的逻辑状态).

The mutable keyword is there to mark members that are not part of the "state" of the class (ie they are some form of cached or intermediate value that does not represent the logical state of the object).

您的相等运算符(以及其他比较器(或任何序列化数据的函数)(或生成散列的函数))定义对象的状态.您的相等比较器在检查对象的逻辑状态时不使用成员z",因此成员z"不是类状态的一部分,因此无法使用可变"访问器.

Your equality operator (as well as other comparators (or any function that serializes the data) (or function that generates a hash)) define the state of the object. Your equality comparitor does not use the member 'z' when it checks the logical state of the object so the member 'z' is not part of the state of the class and is therefore illegable to use the "mutable" accessor.

现在说.我确实认为以这种方式编写代码非常脆弱.类中没有任何东西可以阻止未来的维护者意外地将 z 成为类状态的一部分(即,将其添加到哈希函数中),从而破坏了在 std::unordered_set<> 中使用它的先决条件;.因此,您应该非常明智地使用它,并花费大量时间编写注释和单元测试以确保前提条件得到维护.

Now saying that. I do think the code is very brittle to write this way. There is nothing in the class that stops a future maintainer accidentally making z part of the state of the class (ie adding it to the hash function) and thus breaking the pre-conditions of using it in std::unordered_set<>. So you should be very judicious in using this and spend a lot of time writing comments and unit tests to make sure the preconditions are maintained.

我还会查看@Andriy Tylychko"关于将类分解为常量部分和值部分的评论,以便您可以将其用作 std::unordered_map 的一部分.

I would also look into "@Andriy Tylychko" comment about breaking the class into a const part and a value part so that you could potentially use it as part of a std::unordered_map.

这篇关于使用 mutable 允许修改 unordered_set 中的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆