The beauty of containers in C++11
Containers for storing data are one of many great features of the C++ Standard Library. Despite their advantages, to initialize them, and to loop over them was not always easy. Fortunately, the C++11 standard has made life easier, as I will explain below with examples. Disclaimer: this information has been known to C++ programmers for years, but is only slowly finding its way into our field of science.
The example below shows the initialization of a std::vector
of the std::string
type, and a loop over the vector to print its elements. Especially the loop, which has to define a const_iterator
to get read-only access to the elements of a std::vector<std::string>
container, is not easy to understand for the novice (scientific) programmer.
#include <vector>
#include <string>
#include <iostream>
int main()
{
std::vector<std::string> numbers;
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
for (std::vector<std::string>::const_iterator it=numbers.begin(); it != numbers.end(); ++it)
std::cout << *it <<std::endl;
return 0;
}
Even within the old standard, the piece of code above can be simplified by the declaration of a typedef
as an alias for the container type.
int main()
{
typedef std::vector<std::string> vs;
vs numbers;
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
for (vs::const_iterator it=numbers.begin(); it != numbers.end(); ++it)
std::cout << *it <<std::endl;
return 0;
}
With the C++11 standard (and as we speak, the new C++14 is being implemented in the latest versions of the major compilers), the initialization of a std::vector
, as well as looping over its elements, can be greatly simplified as the example below shows.
#include <vector>
#include <string>
#include <iostream>
int main()
{
std::vector<std::string> numbers = {"one", "two", "three"};
for (const auto& s : numbers)
std::cout << s << std::endl;
return 0;
}
In the initialization, we make use of a so-called initializer list that passes its elements into a specialized constructor that inserts the elements one-by-one into the container.
The range-based for
loop, in combination with the new auto
specifier is another great feature. auto
is able to deduct the type of variable s
based on the container type of numbers
. Note that s
is a const reference, which is the fastest way to provide read-only access to container elements.
C++11 provides great opportunities to simplify C++-based scientific codes. Therefore, we are gradually introducing C++11 elements into MicroHH.