In today's studio you will explore several more advanced features of C++ that support functional programming, including: function pointers, lambdas, and the standard bind function. These features can be used to make containers, algorithms, and programs more powerful and flexible by combining, modifying, and using functions as entities in their own right.
Please complete the following required exercises. I encourage you to please work in groups of 2 or 3 people on each studio (and the groups are allowed to change from studio to studio) though if you would prefer to complete any studio by yourself that is also allowed.
As you work through these exercises, please record your answers, and when
you finish them please log into Canvas, select this course in this semester, and
then upload a .txt
file containing your answers on the Canvas page
for this studio assignment. Only one submission per team, please, and if
you need to re-submit it the person who originally submitted the studio should
please be the one to do that.
Make sure that the name of each person who worked on these exercises is listed in the first answer, and make sure you number each of your responses so it is easy to match your responses with each exercise.
First, ssh into shell.cec.wustl.edu
using your WUSTL
Key id and password and then use qlogin
to log into one
of the Linux Lab machines and then confirm that the version of g++
there is correct (as you did in Studio 0). Then
cd
into your directory for this course this semester, create a new
subdirectory for this studio, and cd
into it.
Define a main function for your program, and in it declare two variables of type
const char *
that are initialized with two different C-style string
constants (e.g., "Hello, "
and "World!"
).
At the top of the source file that contains your program's main function,
include the <cstring>
library header file, which declares
the standard functions that C++ provides for C-style strings.
You should then write statements that (1) print out those C-style strings to the
standard output stream, with each C-style string clearly delimited with additional
characters in the output (e.g., by inserting "\""
into the output
stream before and after each C-style string)
to let you see where each string begins and ends (especially if either of them
starts or ends with a whitespace character); and (2) use the std::strlen
function to print out how long each of those C-style strings is.
Compile and run your program, and as the answer to this exercise please show (1) the code you wrote for this exercise and (2) the output your program produced by running it.
In the main function of your program declare a pointer to a function that
takes a const char *
as its only parameter and returns a value
of type std::size_t
.
Initialize that pointer to point to std::strlen
and modify your
statements that print out the length of the C-style strings so that instead
of calling std::strlen
directly they dereference the function pointer
and call the function that the pointer points to. Note that due to operator
precedence you'll need to surround the dereference with parentheses.
Compile and run your program, and confirm that you see the same output as you did in the previous exercise. As the answer to this exercise please show the code that declares, initializes, and dereferences the function pointer.
At the top of the source file that contains your program's main function,
include the <cmath>
library header file, which declares
the standard mathematical functions that C++ provides, including those
originally provided by C.
In your main function declare a variable of type float
and initialize
it (in that same line) with a non-zero value.
Then, output the value of the variable and the result of calling the
std::sin
function with the result of calling the
std::cos
function with the
float
variable you just declared.
Instead of storing the result that is returned by the call to the
std::cos
function in a variable and then passing that variable
into the call to the std::sin
function, wrap the call to the
std::sin
function around the call to the std::cos
function.
Compile and run your program, and as the answer to this exercise please show the code that you wrote for this exercise and the output it produced.
At the top of the source file that contains your program's main function,
include the <functional>
library header file, which declares
a number of functions and templates for functional programming, which we will
use in the rest of the exercises in this studio.
In your program's main function, declare a variable by appropriately instantiating
the standard function
template and initialize it with a lambda based
on the std::sin
function, as illustrated in today's lecture slides.
Similarly, also declare another variable of the same callable type that is
initialized with a lambda based on the std::cos
function.
Then, output the value of the float
variable from the previous
exercise and the result of calling the first variable you declared for this
exercise with the result of calling the second variable you declared for this
exercise with the float
variable from the previous exercise.
In this exercise as well, please chain the calls to those variables,
by wrapping the call to the first variable around the call to the second one.
Compile and run your program, and confirm that you see the same output as you did in the previous exercise. As the answer to this exercise please show the code that you wrote for it.
Copy the following template source and template header files into your directory
for this studio exercise: Compose_T.cpp
and Compose_T.h
. These files were derived
directly from a code fragment that was provided in the
function composition in C++ / C++11 discussion on stack overflow. Note that this
exercise considers a fairly basic notion of function composition, and many more
sophisticated ideas are explored in that discussion.
Update the Makefile in your directory for this studio exercise so that the
SPECIAL_FLAGS
line contains the flag
-DTEMPLATE_HEADERS_INCLUDE_SOURCE
, Compose_T.cpp
is listed
on the TMPL_SRCS
line, and Compose_T.h
is listed on the
HEADER_FILES
line.
In your main function, declare a variable that has an auto
type
(which will ask the compiler to determine its appropriate callable type) and
initialize that variable with a call to the compose
template function
that is declared and defined (respectively) in Compose_T.h
and Compose_T.cpp
, with the two varibles you declared in the previous exercise
(using the one based on std::sin
as the first argument and the one based
on std::cos
as the second argument). Note that the syntax for
invoking the compose
function template does not require additional
type information to be specified - it is simply of the form
compose(f,g)
.
Then, output the value of the float
variable from the previous
exercises and the result of calling the variable you declared for this
exercise with that float
variable.
Compile and run your program, and confirm that you see the same output as you did in the previous exercise. As the answer to this exercise please show the code that you wrote for it.
In your main function, again declare a variable that has an auto
type
but this time initialize it by passing the variable you declared in the previous
exercise and the float
variable from the previous exercises, into a
call to the std::bind
function.
Then, output the value of a call to the variable you declared for this exercise (using its function call operator, which takes no parameters).
Compile and run your program, and confirm that you see the same output as you did in the previous exercise. As the answer to this exercise please show the code that you wrote for it.
For this studio, please turn in the following:
Page posted Monday September 12, 2022, by Chris Gill.