Friday, January 10, 2014

Chapter:04 Range For Statement

Fundamental
=========


"FOR" loop is one of the most common logic in programming and it's normally used when we want to traverse the each member in sequence. But one fundamental problem with basic for loop is, we need to mention the size for the loop to terminate. This is a problem and a source of error because if there is any mistake while passing the size information, we would be in big trouble. These errors are one of the most common cause of Memory Overflow/Underflow situation.

In C++11, a new range-based for loop has been introduced. Here you don't need to pass any size information of your input sequence. The piece of code which uses this, looks very compact and beautiful. This range-based for loop works for all standard containers and even for default array. Basically any sequence which provides the begin() and end() interface, it should work. So if we plan to write any new container type class, we should provide these interfaces to work well with range-based for loop. begin() and end() interfaces are also required if we want to use the STL defined algorithms anyway.


Range-based for loop with "auto" feature works very smoothly. The old rule applies here as well regarding how we should store a particular member in sequence. If you just want to fetch the members where you do not want to modify "const reference" should be used. In other cases where we want to read and update we should use either by "value" of by "reference".


Uses
===

The below program demonstrates that, how the same piece of code works fine
for almost all sequential type containers which basically provides the begin()
and end() interface.



//Code Begins
#include<iostream>
#include<vector>
#include<string>
#include<list>
#include<array>

template<typename C>
void display_container_elements(C& cnt)
{
 for(const auto& index: cnt)
    std::cout<<index<<"\t";
 std::cout<<"\n";
}

void learn_range_for_loop(void)
{   
 constexpr std::size_t size{5};
 int carray[size]={1,2,3,4,5};
 display_container_elements(carray);

 std::array<int,size> var_a{6,7,8,9,10};
 display_container_elements(var_a);

 std::vector<int> var_b{11,12,13,14,15};
 display_container_elements(var_b);

 std::list<int> var_c{16,17,18,19,20};
 display_container_elements(var_c);

 std::string var_d{"MantoshKumar"};
 display_container_elements(var_d);
}

int main(int argc, const char* argv[])
{
 learn_range_for_loop();
 return 0;
}

//Code Ends





When I run the above program, I get the following output.



//Console Output Begins

$ ./test
1        2    3       4      5   
6        7    8       9    10   
11    12    13    14    15   
16    17    18    19    20   
M    a    n    t    o    s    h    K    u    m    a    r

//Console Output Ends


Now,I can explain how we should use range-for loop in the scenario where we want to modify the elements of sequence. Under this scenario we should not use the 'const reference'. Below code basically stores the "std::string" in "std::array". Now if we want to modify each string value and store back to "std::array" we can do as following example. Later on, I have also printed the elements of  sequence before and after the change. While displaying(just reading), it makes sense that we should use 'const reference'.



//Code Begins

#include<iostream>
#include<string>
#include<array>

void learn_range_for_loop(void)
{   
 constexpr std::size_t  size{3};
 typedef std::array<std::string,size> myarray;
 myarray arr_x{"aa", "bb", "cc"};

 std::string tmp = "xx";
       
 for(const auto& i: arr_x)
   std::cout<<i<<"\t";
 std::cout<<"\n";
                     
 for(myarray::value_type& x: arr_x)
   x = x + tmp;

 for(const auto& i: arr_x)
   std::cout<<i<<"\t";
 std::cout<<"\n";

}



int main(int argc, const char* argv[])
{
 learn_range_for_loop();
 return 0;
}

//Code Ends






When I run the above program, I get the following output which is expected.



//Console Output Begins
\begin{verbatim}
$ ./test
aa    bb    cc   
aaxx    bbxx    ccxx   

//Console Output Ends









No comments:

Post a Comment