I don't think it is allowed to. Copy elision happens in a very limited
set of explicitly listed cases, and they are all about omitting a
temporary when creating a new object, which isn't the case here.
On the other hand, if your copy constructor has no side effect and is
simple enough for the compiler to understand, it will optimize and
remove most of the actions of copying. It depends what is in the body
of your for loop (if it is empty...), but it would require a very
clever compiler for a std::set to fall into this category. For
std::vector<POD>, it seems almost within reach of current compilers.