0% found this document useful (0 votes)
123 views6 pages

Transitioning To Modern C++:: An Overview of C++11/14/17 For C++98 Programmers

This document describes five laboratory exercises for a course on transitioning from C++98 to modern C++. The exercises cover new initialization rules, lambdas, moving vs copying performance, variadic function templates, and using =delete to disable moving while allowing copying. Students are provided with source code files and instructions to complete tasks related to these new C++ language features.

Uploaded by

mciobanu81
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
123 views6 pages

Transitioning To Modern C++:: An Overview of C++11/14/17 For C++98 Programmers

This document describes five laboratory exercises for a course on transitioning from C++98 to modern C++. The exercises cover new initialization rules, lambdas, moving vs copying performance, variadic function templates, and using =delete to disable moving while allowing copying. Students are provided with source code files and instructions to complete tasks related to these new C++ language features.

Uploaded by

mciobanu81
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Transitioning to Modern C++:

An Overview of C++11/14/17 for C++98 Programmers


Lab Exercises

This document describes laboratory exercises for the course.

Each exercise’s basis files are located in a direct sub-folder of the course’s Labs
folder. Solutions are provided in a further sub-folder named Soln.

Remember to use the appropriate compiler options to specify language version.


E.g., for g++, use -std=c++11 for C++11 or -std=c++1y for C++14.

Lab #1: New initialization rules


Folder: Labs\init

This is a paper-and-pen exercise. Please do not use your computer until you
have completed the exercise; at that point, feel free to run the source file
through your compiler to see the exact diagnostics produced.

For each statement marked with // ? in the following program,


determine whether the statement is legal (compiles) or illegal (doesn’t
compile) in C++11/14.

Plus, for each valid ‘auto’ initialization, determine the initializer’s type.

// a) Identify legal vs. illegal C++11 statements


// at each "// ?" comment below.
//
// b) For each legal 'auto' initialization, tell
// what type was deduced for the variable.

constexpr int sum(int a, int b) { return a + b; }

class X
{
public:
X();
explicit X(int);
// ...
};

template<typename T>
void fun(T value, T value2 = T()) {}

int main()
{
int i = 0, j = 1, k = 2;
const double d = 1.2;
const int size = 50;
float f = 2.3;

auto v1 = i; // ?
auto v2(d); // ?
int v3{k}; // ?
int v4{d}; // ?
auto v5{5}; // ?

auto v6 = v1 + v2; // ?
auto v7 = v3 + v5; // ?

int ar1[] { i, j, k, 3, 4}; // ?


int ar2[] { 2, 3, 4, f}; // ?
int ar3[] = { 2, 3, 4, f}; // ?
double ar4[] = { 2, 3, 4, f}; // ?
auto ar5[] = { 2, 3, 4}; // ?

float f2[] = { 2.23, 3.14 }; // ?


float f3[] = { 2.23, d }; // ?

bool ar6[sum(size, 10)]; // ?

constexpr auto c1 = sum(d, 100); // ?


const auto c2 = sum(f, 100); // ?
constexpr auto c3 = sum(f, 100); // ?

X x1(23); // ?
X x2 = 23; // ?
X x3{23}; // ?
X x4 = {23}; // ?

fun(x1); // ?
fun(x1, x3); // ?
fun({x1, x3}); // ?

auto y = {x1, x3}; // ?


fun(y); // ?
}
Lab #2: Lambdas
Folder: Labs\lambdas

Write one-line expressions to:

1. Initialize a vector of integers with the numbers 0 - 99


2. Square the elements of a vector
3. Calculate the sum of squares of a vector
4. Print all even numbers in a vector of integers

Use only standard STL algorithms and lambdas.

Do not use any explicitly written function objects.


Do not write any explicit loops.

Style points: How readable can you make the code?

HINT: If you cannot come up with the standard STL algorithms that provide
a direct path to the solutions, see the file hints.txt, in the solution
folder, for the names of some useful algorithms.

Extra Credit:

Now that you have written several lambdas, write the function object types
yourself that the lambda expressions you wrote automatically created, and
then invoke them explicitly in place of the lambdas your wrote earlier.

Lab #3: Performance characteristics of moving vs. copying


Folder: Labs\moving

For the following timing tests, run each executable at least 3-4 times until
the timer results stabilize (the first few runs will probably take longer as
system caches are getting saturated.)
Given a non-move-enabled class Widget and test program
loadwidgets.cpp,

1. Compile loadwidgets.cpp with widget.cpp, and note the run


time. Output should indicate that no move operations have been invoked
(since, in this version of the program, move operations are not present.)

2. In loadwidgets.cpp, uncomment the "reserve" call to the vector,


and compile/time it again.

3. Implement move operations (move constructor, move assignment


operator) for Widget in widget.cpp (using the skeletons provided
within the conditional compilation block).

Please be sure to uncomment the


#define WIDGET_MOVE_ENABLED
line in Widget.h.

4. Compile and time again, both with and without the vw.reserve()
call.

What conclusion can you draw about the relative performance benefit of
using reserve on a vector for move-enabled vs. non-move-enabled
types?

Lab #4: Implementing a variadic function template


Folder: Labs\variadic

In this lab, you’ll be implementing part of a variadic function template pair


that serves as “helpers” for a tuple-printing utility function.

The source file is print_tuple.cpp. The test driver appears as follows:


template<typename... Args>
void print_tuple(const tuple<Args...> &t);
int main()
{
int n = 42;
double sqrt5 = 2.2360679774;
string s = "Some text";

auto t = make_tuple(n, sqrt5, s);

print_tuple(t);
}

When executed, the output is:


{42, 2.23607, Some text}

The print_tuple function template is implemented for you, in terms of


a helper class template (pair) named print_tuple_helper. Each class
of the pair contains a member function named print, one for the “general”
case (for you to implement), and one for the “terminal” case (implemented
for you.)

Examine the code and implement print for the general case variadic
helper class template print_tuple_helper.

HINT: Keep in mind that print_tuple_helper specializations are


names of classes.

Lab #5: What's the right way to design a class to be copyable but not
movable? Or, “Fun with =delete”
Folder: Labs\delete

You are given the source file widget.cpp, containing a skeletal Widget class and
a main function that exercises default construction, copy construction and copy
assignment.
1. Implement the following member functions for Widget, with tracing
messages:

a) default construction
b) copy construction
c) copy assignment

Do NOT declare any move operations.

2. Implement the factory function getWidget() that returns an instance


of a Widget by value.

3. Test your Widget and factory function implementation by compiling


and executing the program. Given the rules of move operation generation,
is Widget "move-enabled"? How are objects returned from the factory
function?

4. Now implement the two move operations for Widget, with tracing
messages. Test to see if they are getting called when appropriate. If they
aren't, that is probably because your compiler is applying the Return Value
Optimization rather than utilizing your move operations. To force a move
construction, add a statement such as the following:
Widget w4(move(w3));

(where, in this case, w3 is a previously defined Widget). This should force


at least the move constructor to be used. Test to make sure.

5. Now, let's say you decide you don't want move operations to exist for
Widgets. Remove your implementations of the two move operations, and
instead define both of the operations as =delete in the class definition.

6. Does your program compile now? (It shouldn't. If it does, see me.)
So, why doesn't it compile? How would you "fix" this situation so that no
move operations exist and the program compiles?

You might also like