Discount for my course: High Performance Coding with .NET Core and C#

Gergely Kalapos


Range based for loop in C++11 and the '&' sign

Posted on September 10, 2014



This is a short post on the new range based for loop in C++11 and a short summary about an ~1h debugging session and its conclusion.

So in C++11 we can write this:


  for(auto fk : forignKeys) {
                …
  }

forgnKeys is a std::vector<ForignKeyRelation>, where ForignKeyRelation is my own class.

Now… why is this for statement above most of the time wrong? The answer is because the items are copied into the fk variable at each iteration step. This is 1) overhead 2) if you change fk you don’t change the items in your vector.

My original code was this:



    int nMatch = 0;
    for(auto fk : forignKeys) {
        for(auto& table: tables){
            if(fk.GetReferencedTableName() == table.name_){
                fk.SetReferencedTable(&table);
                nMatch++;
            }
            if(fk.GetReferencingTableName() == table.name_){
                fk.SetReferencingTable(&table);
                nMatch++;
            }
        }
    }

Of course all the fk.SetReferencedTable lines changed only copies from the original vector, but the items in the vector remained unmodified. 

So let’s see what the options are with range based for loop in C++11:

  • for(auto myVar : myVector): As I described before the items are always copied into the myVar variable. So modifications on myVar are invisible in the original vector. 

  • for(auto& myVar : myVector): This time the type of myVar is auto&, so we have a reference here! And this is exactly what I wanted. The current item from the vector is not copied, instead of copying a reference is created, so if we modify anything on myVar we basically modify the item in the vector.

  • for(auto const& myVar: myVector): If you want to make sure that the items in the vector are not changed but don’t want to copy the items you can also create an auto const&. Every time you call a non const function on myVar, or you want to change a value on it the compiler throws an error. 

And that’s it. My correct code is this (spot the added &!!):



    int nMatch = 0;
    for(auto& fk : forignKeys) {
        for(auto& table: tables){
            if(fk.GetReferencedTableName() == table.name_){
                fk.SetReferencedTable(&table);
                nMatch++;
            }
            if(fk.GetReferencingTableName() == table.name_){
                fk.SetReferencingTable(&table);
                nMatch++;
            }
        }
    }



;