There's no way to avoid the copy, since a std::vector<T> is a distinct type from std::vector<U>, and there's no way for them to share the memory. Other than that, it depends on how the data is mapped. If the mapping corresponds to an implicit conversion (e.g. unsigned short to bool), then simply creating a new vector using the begin and end iterators from the old will do the trick:
std::vector<bool> newV( oldV.begin(), oldV.end() );
If the mapping isn't just an implicit conversion (and this includes cases where you want to verify things; e.g. that the unsigned short does contain only 0 or 1), then it gets more complicated. The obvious solution would be to use std::transform:
std::vector<TargetType> newV; newV.reserve( oldV.size() ); // avoids unnecessary reallocations std::transform( oldV.begin(), oldV.end(), std::back_inserter( newV ), TranformationObject() );
, where TranformationObject is a functional object which does the transformation, e.g.:
struct ToBool : public std::unary_function<unsigned short, bool> { bool operator()( unsigned short original ) const { if ( original != 0 && original != 1 ) throw Something(); return original != 0; } };
(Note that I'm just using this transformation function as an example. If the only thing which distinguishes the transformation function from an implicit conversion is the verification, it might be faster to verify all of the values in oldV first, using std::for_each, and then use the two iterator constructor above.)
Depending on the cost of default constructing the target type, it may be faster to create the new vector with the correct size, then overwrite it:
std::vector<TargetType> newV( oldV.size() ); std::transform( oldV.begin(), oldV.end(), newV.begin(), TranformationObject() );
Finally, another possibility would be to use a boost::transform_iterator. Something like:
std::vector<TargetType> newV( boost::make_transform_iterator( oldV.begin(), TranformationObject() ), boost::make_transform_iterator( oldV.end(), TranformationObject() ) );
In many ways, this is the solution I prefer; depending on how boost::transform_iterator has been implemented, it could also be the fastest.
std::vector<bool>is specialized to be memory efficient.vector<bool>is a disaster. Even STL authors admit it was a mistake.