In your code without std::inserter
, transform
assigns to *b.begin()
. In the case of set
that's a const reference to an element (since C++11). Hence, a compile-time error.
In the case of the list
it still assigns to *b.begin()
, which compiles but has undefined behavior because the list has size 0. So b.begin()
may not be dereferenced.
You are correct that this is to do with the fact that set
is an associative container whereas list
is a sequence. Associative containers don't let you modify the part of the element used as a key. In the case of set
that part is the element, for map
you can modify the value but not the key.
The whole point of std::inserter
is to arrange that instead of assigning through an iterator, it calls insert
.