There's a 4th requirement: that the set has some way to return colliding entries on insertion (or provides access to the entry itself), which most don't. Otherwise lookup requires iterating the entire set.
> It's straightforward
It's really not. Straightforward is the other way around, this is convoluted and involved. It makes the library much harder to use for rather limited gains.
> Either the set type allows mutation of the objects so long as the parts relevant to comparison don't change
This sounds like a footgun requirement at best, I'm pleasantly surprised (for once) that C++ doesn't just let you mutate the entire thing at will.
> It's straightforward
It's really not. Straightforward is the other way around, this is convoluted and involved. It makes the library much harder to use for rather limited gains.
> Either the set type allows mutation of the objects so long as the parts relevant to comparison don't change
This sounds like a footgun requirement at best, I'm pleasantly surprised (for once) that C++ doesn't just let you mutate the entire thing at will.