C++ Container classes
In ROOT and C++, there are a couple of general categories of containers you have to know about.
Arrays
Do a web search on “C++ arrays” to learn about these containers.1 Briefly, to create a double-precision array of eight elements, you could say:
Double_t myArray[8];
To refer to the 3rd element in the array, you might use (remember, in C++ the first element has an index of 0):2
Int_t i = 2;
myArray[i] = 0.05;
Getting confused? Let’s keep it simple. If you’ve created arrays with values and errors…
Double_t xValue[22];
Double_t xError[22];
Double_t yValue[22];
Double_t yError[22];
…and you’ve put numbers into those arrays, then you can create a
TGraphErrors
object with:
auto myPlot = new TGraphErrors(22,xValue,yValue,xError,yError);
Array size
Did you notice a problem with that example? I had to supply a fixed value for the number of points in each array to make the plot. In general, you won’t be able to do that; in fact, in subsequent exercises you can’t do that.
In C++, one way to get around this problem is to use “dynamic arrays.” I’ll let you read about those on the web (search on “C++ dynamic arrays”), but I’m not going to say more about them, because I rarely use them.
C++ Standard Template Library (STL)
Do a web search on “standard template library”. Skim a few sites, especially those that contain the words “introduction” or “tutorial”. You don’t have to get too in-depth; for example, you probably don’t have enough time today to fully understand the concept of iterators.
My preference
Did you guess that STL is my preferred method of using containers in C++?
The Standard Template Library is an important development in the C++ programming language. It ties into the concepts of design patterns and generic programming, and you can spend a lifetime learning about them.3
Vectors
You only need one
For the work that you’ll be asked to do in the Advanced Exercises, Expert Exercises, and probably for the rest of this summer, there’s only one STL class you’ll have to understand: vectors.4 Here are the basics.
If you want to use vectors in a program, or even a ROOT macro, you have to put the following near the top of your C++ code:
#include <vector>
To create a vector that will contain a certain type, e.g., double-precision values:
std::vector<Double_t> myVector;
If you want to create a vector with a fixed number of elements, e.g., 8:
std::vector<Double_t> myOtherVector(8);
To refer to a specific element of a vector, use the same notation that you use for C++ arrays:
myOtherVector[2] = 0.05;
The main reason to use vectors for these Exercises is that it’s easy to add a new
value to the end of a vector.5 To append a value to a vector, use the push_back()
method:
myVector.push_back( 0.015 );
To find out the current length of a vector, use the size() method:
Int_t length = myVector.size();
Here’s a simple code fragment that loops over the elements of a vector and prints them out.
for ( size_t i = 0; i != someVector.size(); ++i ) {
std::cout << "The value of element " << i
<< " is " << someVector[i] << std::endl;
}
You have a vector, but TGraphErrors expects C++ arrays. Here’s the trick to convert a vector to an array:6
// Define four vectors.
std::vector<Double_t> x,y,ex,ey;
// Put values in the vectors (omitted so you can do it!)
// Use .data() to convert the vector to an array.
Int_t n = x.size();
TGraphErrors* plot = new TGraphErrors(n, x.data(), y.data(), ex.data(), ey.data());
We’re getting closer to being able to tackle the first advanced exercise!
- 1
If you’re doing these exercises in Python: You’ll want to use numpy arrays instead. Fortunately, numpy arrays will automatically be converted to C++ arrays when they’re passed as arguments to ROOT methods.
- 2
If you’re new to C++, it won’t be obvious that while
myArray[2]
is aDouble_t
object, the type of the namemyArray
(without any index) isDouble_t*
, or a pointer to aDouble_t
.- 3
You may be tired of the joke, but I’m not!
- 4
In Python terms, a C++ vector is like a list that can contain only one type; you can have a vector of integers or a vector of real numbers, but you can’t (easily) have a vector that contains both data types.
- 5
Adding a new element to the end of a C++ array is tricky, since arrays are supposed to be of a fixed length. That’s why I prefer vectors over arrays.
- 6
Advanced note: In other words, if
v
has the typestd::vector<Double_t>
, thenv.data()
is equivalent to the underlyingDouble_t
array.