C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Alteration of elements in a set (non-const iterator)

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 21 May 2023 17:42:59 -0400
On Sun, May 21, 2023 at 5:09 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> I wrote the following code today; I have a struct for storing an IP
> address as well as two booleans (one for a FTP server and one for a
> Samba file server):
>
> struct IPFileShare {
> std::uint32_t ip;
> bool ftp, smb;
>
> IPFileShare(uintIP const arg) : ip(arg), ftp(false), smb(false) {}
>
> bool operator<(IPFileShare const &rhs) const { return this->ip <
> rhs.ip; }
> };
>
> std::set<IPFileShare> myset;
>
> As you can see, the sorting operator only takes into account the IP
> address. The other two members of the struct, 'ftp' and 'smb', have no
> effect on the sorting of the items in the set.
>
> After having added an item to the set, I want to change the values of
> the two booleans, which should be fine because these booleans have no
> effect on the sorting. I wrote the following code to achieve this:
>
> const_cast<bool&>(myset.insert(ip.num).first->ftp) = true;
>
> I think strictly speaking, the Standard says that this is undefined
> behaviour. How about we change the Standard to say that this
> const_cast is allowed so long as it has no effect on the sorting?
>

No.
The Standard ways to achieve this are:
- mark the `bool` as `mutable`,
- use a std::map<uintIP, OtherPartsOfTheIPFileShare> instead of a
std::set<IPFileShare>, or
- since C++17:

    auto it = myset.insert(ip.num);
    auto nh = myset.extract(it);
    nh.value().ftp = true;
    myset.insert(nh); // Admittedly this does do one additional find()
compared to the other two methods

–Arthur

Received on 2023-05-21 21:43:12