Frequently Asked Questions

1. What are the files with the extension txx or tpp?

In C++ the full implementation of a template must occur in the same translation unit. Thus they cannot be compiled and linked seperately. It is still convienint to have seperate files for the definition and implementation. The solution is simply to use the include macro.

Here is a minimal example of a template class with definition in a header and implementation in a .txx.

Contents of example.h

#ifndef _EXAMPLE_H
#define _EXAMPLE_H
template <typename T>
class Example
{
public:
    void SomeMethod();
};
#include "example.txx"
#endif 

Contents of example.txx

#include "example.h"

template<typename T>
Example<T>::SomeMethod(){}

Client code using the class

#include "example.h"

Example<int> myexample;

The .txx extension is just the convention I use. Your book uses a normal C++ file extension. I think this confuses things because they cannot be compiled standalone.

As an aside this is one reason why code that uses templates heavily can be slow to compile since the compiler might have to parse template code several times, generating intermediate code that just has to be discarded later.

2. What are include guards?

C++ has a one-definition-rule -- you cannot define a variable, function, or struct/class but once. This can become an issue when header files are used to define modules of code. Often one header includes another which then includes the first, leading to a cyclic dependency and a violation of the one-definition rule.

The portable solution is to use include guards. In each header file surround the definitions with macros that check if a macro symbol is defined, and if not define it.

#ifndef _EXAMPLE_H
#define _EXAMPLE_H

// code here

#endif 

When the file is first encountered the symbols is not define and the code is parsed. Subsequent times the file is included the code is skipped because the symbol was defined. The exact name of the macro symbol does not matter as long as it is unique. This is easily accomplished by making it a mangled version of the file name, as above.

Another way of doing this is to use a compiler specific macro called a pragma. You can place the macro #pragma once and the top of each header and ommit the include guards. While all modern mainstream compilers support pragma once, it is not part of the standard (yet). It is common to find older compiler toolchains (e.g. for embedded systems) that do not. So, the use of include guards is still more portable and the recommended way to deal with this problem. Many compilers have optimizations for include guards so that they do not even read the file but once.

Note that this is one of the very-few ligitimate uses of macros in modern C++.

3. How do command line arguments work?

Recall the primary ways to get user input into a program, standard input (std::cin) and reading from files. Another very convienent one is to use command line arguments. When your program is run, usually from another program (the operating system or a shell program), it starts executing in the function main. This is called the entry point.

int main()
{
    //code here
    
    return 0;
}

There is another form of this entry pointwith two arguments. The first (traditionally named argc) is the number of string arguments to the program, the second (traditionally named argv) is an array of ``argc'' C-style strings (pointers to null-terminated memory) with the arguments themselves.

int main(int argc, char*argv[])
{
    //code here
    
    return 0;
}

You can specify the command line arguments when you run the program from a text shell (e.g. cmd.exe or powershell), from a graphical shell (like when you click on an icon), or from a script (e.g. a bat file).

It is easy to convert the more C-style arguments to a more modern C++ style as follows

#include <vector>
#include <string>

int main(int argc, char*argv[])
{
    std::vector<std::string>  arguments;
    for(int i = 0; i < argc; ++i) arguments.push_back(argv[i]);
    
    // code can use arguments as a C++ vector of C++ strings 
    
    return 0;
}

The most common use of command line arguments is to be able to run a program easily with different inputs, often filenames to use. A common followup question is why is this better than just prompting for input with standard output and standard input (''std::cout'' followed by ''std::cin'')?

Than answer is that such input is difficult to automate. Scripts are one of the best ways to combine programs and often need to run unattended. A prompt blocks the program until a user hits return, requiring a user to be present and attending to the task. A script can also use the output of one program as the command lien argument to another, allowing one to mix and match smaller programs into a single task. This is one of the core philisophies in computing.

4. Why does main return an int?

A related question to the previous is why does main return an int anyway? Well, when your program is run to completion it can indicate to the running process if it succedded or if an error occured by returning this int. Success is defined as zero, which is why most simple examples returns that. The following are defined in the header ''cstdlib'': ''EXIT_SUCCESS'' and ''EXIT_FAILURE'', and can be used when returning from main.

Note you do not have to call return in main (this is a special case). In such cases the compiler inserts a success return for you.

5. What are the projects ''ALL_BUILD'', ''RUN_TESTS``, and ''ZERO_CHECK'' in the Visual Studio solution file generated by cmake?

To build all code and tests you do a build on the ''ALL_BUILD`` project. To run the tests within Visual Studio you do a build on the ''RUN_TESTS'' project. Building the ''ZERO_CHECK'' project will re-run cmake from within Visual Studio -- needed if you change the CMakeLists.txt file.

6. After running CMake and opening the solution file in VS, I can't run the debugger, it says "unable to start program"

You first need to make the VS project (for the executable you are trying to debug) the startup project. Right click on the project in the solution explorer window and select "set as startup project".

7. How do I provide command line arguments to my programs

There are (at least) two ways.

The first works within Visual Studio. It is best if you want to run the debugger. In the solution explorer right click on the project for the executable of interest and select properties. Click on Debugging in the left panel. Then click on the entry box to the right of Command Arguments in the right panel. Provide or edit the command line string and save. These will be passed to the executable when you run the program within VS, with or without the debugger. This has to be repeated each time you want to change the arguments, which can be inconvenient.

The second is from the command line. It more convenient and is best for manual testing. Run the program cmd.exe. Locate the executable within the file explorer (it is usally in the Debug subdirectory of the build directory). Copy the path to the clipboard. Switch back to the cmd window and type 'cd' and then right-click paste, then hit enter. This changes the current directory to the one containing the executable. You can now run it by typing the executable name followed by the command line arguments.

8. How do I create a zip archive for submission on Windows?

Open your source folder in File Explorer. Cntl-click on the files you want to add to the zip file, then right-click, send-to, compressed folder.

9. How do I make Visual Studio highlight the .txx files as C++ code?

In the menu bar open tools-options. Scroll down to Text Editor and expand the tree view. Click on File Extension. Under Editor in the right pane, select Microsoft Visual C++. Then type the extension (e.g. .txx) in the box immediately to the left. Then hit add.