Archive

Posts Tagged ‘std::copy’

back_inserter explained

back_inserter stl iterator class is an adapter class. So what is an adapter? If you buy a laptop in India and then take it to the US/Europe, plugs given won’t fit into the sockets there, so what we do is buy an adapter, which adapts our laptop’s plug to the sockets there. Adapter pattern based class adapts an existing functionality to a close relative of it’s own. Similarly back_inserter adapts a normal iterator to a more dynamic one, which means inserts an element into a vector by increasing it’s size i.e. push_back.

Back_inserter can be given as an iterator to stl algorithms. Lets take a case of reading a file. We don’t know how much bytes are there in a file, so what we do is iterate through to the end of the file along with inserting read in bytes to a vector. This functionality requires a loop, but with back_inserter, we just need one line of code. Here is a demo…

typedef std::vector<char> BytesVector;
BytesVector FileBytes;
std::ifstream file( "C:\\umdhlog.log" );
std::copy( std::istream_iterator< char >( file ), // Starts iterating file
           std::istream_iterator< char >(), // Dummy param to denote EOF
           back_inserter( FileBytes )); // Inserts elements to a vector

Last parameter to std::copy is the key, it’s a back_inserter object. Also note that we’ve given an empty vector and not a resized one. Key to this behavior is the way in which back_inserter behaves, when it inserts an element to a vector it in fact does a push_back. Had we given FileBytes.begin() instead of back_inserter( FileBytes ) there will be a crash.

Another example to fill in a vector with hundred random numbers using back_inserter…

typedef std::vector<int> IntVector;
IntVector Ints;
std::generate_n(std::back_inserter( Ints ), 100, rand);

A close relative of back_inserter is front_inserter used mainly with std::lists.

Dumping contents of a vector/list to cout

August 2, 2008 Leave a comment

Is it possible to do this with just one line of code? Oh yes!

Have a look…

typedef int VT;
typedef std::vector VTVec;

void Dump( VTVec& VecToPrint, std::ostream& stream, const char* lpszMsg )
{
// We will be wrapping every element within a square bracket.
// In the end output looks like this… [123] [864] [
stream << lpszMsg << "["; // Get iterator for given stream, every element will be seperated with second // parameter. std::ostream_iterator Itr( stream, "] [" ); // Just one line to dump vector contents, no loops needed std::copy( VecToPrint.begin(), VecToPrint.end(), Itr ); // Remove redundant space and bracket ( " [" ) from the end // After this statement the series will look like [123] [864] stream << "\b\b \b\b\n"; }// End Dump int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { VTVec VecObj( 10000, 0 ); // Fill vector with random number, see earlier post on std::generate std::generate( VecObj.begin(), VecObj.end(), rand ); // Dump to std::cout Dump( VecObj, std::cout, "Dumping vector of ints...\n" ); }// End _tmain[/sourcecode]