Online Book Reader

Home Category

Professional C__ - Marc Gregoire [287]

By Root 1394 0
doubles instead of integers, you also need to modify the call to gen():

int rnd = static_cast(gen());

Figure 16-2 shows a graphical representation of the random numbers generated according to the normal distribution.

FIGURE 16-2

The graph clearly shows that most of the generated random numbers will be around the center of the range. In this example, the value 50 will be randomly chosen around 40,000 times, while values like 20 or 80 will be chosen randomly only around 500 times.

TUPLES


The std::pair class, introduced in Chapter 12, can store two values, each with a specific type. The type of each value should be known at compile time. The following is a short example:

pair p1(16, "Hello World");

pair p2(true, 0.123f);

cout << "p1 = (" << p1.first << ", " << p1.second << ")" << endl;

cout << "p2 = (" << p2.first << ", " << p2.second << ")" << endl;

Code snippet from Tuple\pair.cpp

The output is as follows:

p1 = (16, Hello World)

p2 = (1, 0.123)

C++11 introduces the std::tuple class, defined in the header file. A tuple is a generalization of a pair, and allows you to store any number of values, each with its own specific type. Just like a pair, a tuple has a fixed size and fixed value types, determined at compile time.

A tuple can be created with a tuple constructor, specifying the template types and specifying the actual values. For example, the following code creates a tuple where the first element is an integer, the second element a string, and the last element a Boolean:

typedef tuple MyTuple;

MyTuple t1(16, "Test", true);

Code snippet from Tuple\tuple.cpp

std::get() is used to get the i-th element from a tuple, where i is a 0-based index; that is <0> is the first element of the tuple, <1> is the second element of the tuple and so on. The value returned will have the correct type for that index in the tuple:

cout << "t1 = (" << get<0>(t1) << ", " << get<1>(t1)

<< ", " << get<2>(t1) << ")" << endl;

// Outputs: t1 = (16, Test, 1)

Code snippet from Tuple\tuple.cpp

You can check that get() returns the correct type by using typeid(), from the header. The output of the following code should say that the value returned by get<1>(t1) is indeed a std::string:

cout << "Type of get<1>(t1) = " << typeid(get<1>(t1)).name() << endl;

// Outputs: Type of get<1>(t1) = class std::basic_string// struct std::char_traits,class std::allocator >

Code snippet from Tuple\tuple.cpp

The exact string returned by typeid() is compiler dependent. The preceding output is from Visual C++ 2010.

The size of a tuple can be queried with the std::tuple_size template. Note that tuple_size requires you to specify the type of the tuple (MyTuple in this case) and not an actual tuple instance like t1:

cout << "Tuple Size = " << tuple_size::value << endl;

// Outputs: Tuple Size = 3

Code snippet from Tuple\tuple.cpp

Another way to create a tuple is to use the std::make_tuple() utility function. This function only needs the actual values and will deduce the types automatically at compile time. Because of the automatic deduction of types, you cannot use & to specify a reference. If you want to use make_tuple() to generate a tuple containing a reference or a constant reference, then you need to use ref() or cref(), respectively, as is demonstrated in the following example. The ref() and cref() helpers are defined in the header file. For example, the following make_tuple() call will result in a tuple of type tuple:

double d = 3.14;

string str1 = "Test";

auto t2 = make_tuple(16, ref(d), ref(str1), cref(str1));

Code snippet from Tuple\tuple.cpp

To test the double reference in the t2 tuple, the following three lines of code first write the value of the double variable to the console. It then uses get<1>(t2), which will actually return a reference because ref() was used for the second tuple element. The second line changes the value of the variable referenced

®Online Book Reader