Home > C++, VC++ > Using std transform function

Using std transform function

So what does std::transform function do?

“Applies a specified function object to each element in a source range or to a pair of elements from two source ranges and copies the return values of the function object into a destination range.”

Some general applications of using transform is as follows…

  1. For doing some kind of operation on two vectors of same type and storing the result in a third vector.
  2. For doing some kind of in place operations on a vector.

So simplified prototypes of this function…

template<class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform( InputIterator _First1,
                          InputIterator _Last1,
                          OutputIterator _Result,
                          UnaryFunction _Func );
template</class><class InputIterator1, class InputIterator2, class OutputIterator, class BinaryFunction>
OutputIterator transform( InputIterator1 _First1,
                          InputIterator1 _Last1,
                          InputIterator2 _First2,
                          OutputIterator _Result,
                          BinaryFunction _Func );

So first prototype can take two different vectors or can be the same vector for inplace modification,while second one takes three, two source vectors (for e.g. two vector of ints and we add these two vectors and place the result in a third vector).

The applications of this function is powerful! Here are some demos

// Starts here
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
   void Demo_Std_TransformInplace();
   Demo_Std_TransformInplace();

   void Demo_Std_Transform_Binary();
   Demo_Std_Transform_Binary();

   return 0;
}

#include <vector> // for std::vector
#include <algorithm> // for std::transform

// Callbacks used with std::transform, can also be functors but for ease of calling //
// Unary operations. Note that I am alternating 'class' and 'typename' keywords just
// to prevent code formatting errors in HTML.
template<class T> T Square( const T Elem ) { return Elem * Elem; }
template<typename T> T ReverseSign( const T Elem ) { return -Elem; }
template<class T> T IncrementBy1( const T Elem ) { return Elem + 1; }
template<typename T> T DecrementBy1( const T Elem ) { return Elem - 1; }

// Binary operations
template<class T> T Add( const T Elem1, const T Elem2 ) { return Elem1 + Elem2; }
template<typename T> T Multiply( const T Elem1, const T Elem2 ) { return Elem1 * Elem2; }
template<class T> T Divide( const T Elem1, const T Elem2 ) { return Elem1 / Elem2; }
template<typename T> T Substract( const T Elem1, const T Elem2 ) { return Elem1 - Elem2; }

// A typedef for ease of use
typedef double VectorType; // Change this type and see the result
typedef std::vector<vectortype> VTVector; // Vector typedef
const VTVector::size_type Size = 1000; // Default size, increase to test performance

// Randomly fills in a vector
void FillInIntVector( VTVector& Vec )
{
   for( VTVector::size_type Index = 0; Index < Vec.size(); ++Index )
   {
      Vec&#91;Index&#93; = static_cast<VectorType>( rand() );
   }
}

// Functions for testing std::transform, Debug through and see the results //
void Demo_Std_TransformInplace()
{
   VTVector VTObj( Size );
   FillInIntVector( VTObj );

   // Do some in place operations
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), Square</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), ReverseSign</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), IncrementBy1</vectortype><vectortype> );
   std::transform( VTObj.begin(), VTObj.end(), VTObj.begin(), DecrementBy1</vectortype><vectortype> );
}

void Demo_Std_Transform_Binary()
{
   // Randomly fill in first vector
   VTVector VTObj1( Size );
   FillInIntVector( VTObj1 );   

   // Randomly fill in second vector
   VTVector VTObj2( Size );
   FillInIntVector( VTObj2 );

   // Added result will be placed in here
   VTVector Result( Size );

   // Add "VTObj1" and "VTObj2" vector place the result in "Result"
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Add</vectortype><vectortype> );
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Multiply</vectortype><vectortype> );  
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Divide</vectortype><vectortype> );
   std::transform( VTObj1.begin(), VTObj1.end(), VTObj2.begin(), Result.begin(), Substract</vectortype><vectortype> );
}

Advertisements
Categories: C++, VC++ Tags: , , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: