CSE 428S: Studio 1

Function and Class Templates


Today's lecture and studio focus on how function and class templates impose requirements on the types with which they are parameterized, and in doing so define sets of types that can be used to parameterize them. Those sets of types establish domains within which interface polymorphism can support the Liskov Substitution Principle, thus allowing types to be designed to work with particular templates by providing the necesary operations and member functions to allow that. Note that even non-template functions and classes may impose different requirements on the types they use, which we will explore at the beginning of this studio.


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 in a manner that makes it easy to match your responses with each exercise.


Required Exercises

  1. As the answer to the first exercise, list the names of the people who worked together on this studio.
  2. 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.

    Copy the Makefile from your previous studio into that directory. As you work on this studio, please update the Makefile as needed so that it will build an executable program called studio1 from the files in that directory.

    Add a header and source file to your directory, and in them declare and define a struct that has a single (public) member variable of type int, and a (public) constructor that takes an int and (in its base/member variable initialization list) uses it to initialize the member variable.

    Add a source file to your directory and in it define your program's main function so that it constructs two objects of the struct type with different int variables, prints out their member variables with a space in between them to the standard output stream (cout), and returns a descriptively named symbol that has value 0 to indicate success.

    Compile and run your program, and as the answer to this exercise please show (1) your code and (2) the ouput the program produced.

  3. In your struct declaration, try adding =delete declarations that suppress the compiler's synthesis of the (1) copy constructor, (2) copy assignment operator, and (3) destructor for the struct (please see LLM pp. 507 for examples of the appropriate syntax to use for doing that). Try adding each of them one at a time, try to build your program, and if it won't compile commenting out that particular =delete declaration so that you can see exactly which of those the main function requires and which of them it doesn't.

    As the answer to this exercise please show the lines of code that you added for this exercise, and for the lines that had to be commented out please explain briefly why it could not be compiled.

  4. In your struct declaration, comment out any of the lines you added in the previous exercise that are not commented out already.

    In your main function, after it prints out the objects' member variables, pass the objects themselves (not their member variables) into a call to the std::swap function template and again print the objects' variables to the standard output stream to show that their values have been reversed. Compile and run your program and as the answer to this exercise please show the output it produced (with the objects' values before and after the swap).

  5. In your struct declaration, try uncommenting the =delete declarations that suppress the compiler's synthesis of the (1) copy constructor, (2) copy assignment operator, and (3) destructor for the struct. Again do this one at a time, trying to build your program each time and if it won't compile again commenting out that particular =delete declaration so that you can see exactly which of those is required and which of them isn't.

    As the answer to this exercise please show all the =delete declarations (including those that were commented out and those that were not), and based on which if them had to be commented out (and which of them did not need to be) please explain whether the std::swap function template imposes additional requirements on the struct type (beyond those imposed by the main function) and if so what those are.

  6. Modify the declaration and definition of your struct so that it is a struct template with a single parameterized type that defaults to int and then modify your main function so that it declares its objects with empty type parameter lists.

    Modify the header and source files for your struct template so that the header file includes the source file, and modify your Makefile so that it treats the source file as a template source file and does not try to compile it directly.

    Compile and run your program, and ensure that it produces the same output as before. As the answer to this exercise please show your code with those modifications.

  7. Modify the declaration and definition of your template so that it is a class instead of a struct, its member variable is private, and all of its member functions are public.

    In the header and source file for the class template, declare and define a template for a left shift operator (operator<<) that takes a reference to an ostream and a const reference to an object of the class type, inserts the object's private member variable to the ostream, and returns a reference to the ostream. Be sure to include the necessary library header file and to add a using std::ostream; statement.

    In your class, declare that operator to be a friend of the class, so that it can access the object's private member variable (LLM pp. 665 has a good example of the kind of syntax you will need to use in order to do that).

    Add any forward declarations of the class template or of the left shift operator that are needed (to the header file for your class template), so that your code will compile. Build and run your program and confirm that it produces the same output as before. As the answer to this exercise please show the code in the header file.

Things to Turn In:

For this studio, please turn in the following:


Page posted Sunday October 23, 2022, and updated Tuesday October 25, 2022, by Chris Gill. Changes since original posting: