I wouldn’t even go that far but more that even in languages like C++ or Rust, which generally are supposed to be used value-identity based (and at least these days are most of the time), you can generally do that.
The problem is more the combination of value-identity based + struct are plain data without inherent behaviour (also known as plain old data).
What tripped me up a little is that allocator interfaces can be copied and are frequently copied, and I learned that “interface” pattern before learning about the reader/writer interfaces. If the goal is to prevent new users from making these mistakes, it would help to have one very consistent pattern for dealing with the interfaces in the std library, even at the expense of a tiny loss in performance in some cases.
Or, just let people learn from their mistakes and eventually they’ll get it. ;^) It is Ok to give people the rope to hang themselves if you’re up front about it, and other factors are more important. I prefer that to the unbounded complexity of languages that try to prevent all such problems. However, whatever consistency and clear naming can be afforded will definitely help and will be greatly appreciated, even if there are three patterns for three different types of interfaces.
Aha! While the allocator interface can be copied, the allocator interface itself is used as const, so copying it everywhere is fine. You won’t modify the allocator itself; you’ll only use it indirectly through its internal pointer.
The writer interface is different in that when you copy it, you copy it as var. Copying a mutable structure is dangerous. So the way to check whether you’re using it correctly is simple: check whether the thing you’re copying is const or var. If the thing you’re copying must be used as a var, then you’re copying incorrectly!