Function Templates In C++

We looked at a very straightforward class template last time, which should have given you the confidence to get started in creating your own template classes.

Now, to round off this introduction to C++ templates, we’ll just have a quick look at function templates, and talk a little more about the workings behind template source code.

As usual, we’ll start with the code, and then dissect it below in order to understand what is going on.

Here’s an example program:

#include <iostream>
#include <string>

using namespace std;

template<class T>
void printdata(T); //function declaration

int main()
{
    int x = 34567;
    string tmp = "hello";
    double y = 3.162;

    printdata(x);
    printdata(tmp);
    printdata(y);

    return 0;
}

template<class T>void printdata(T t) //function definition
{
    cout << t << endl;
}

Okay, so if you run this code, it will output:

34567
hello
3.162

If we look at what’s going on, we’ve got one function (print data). Anything we pass to it, it prints out.

Unlike a regular function, we don’t have to specify a particular argument type to pass in. If we couldn’t use template functions, we’d have to declare three individual functions that took a defined parameter each time (int, string, double). Instead we use the template syntax and tell the function that we will pass a type “T” called “t”.

This follows the familiar format of normal function arguments – e.g. saying we will pass a type int called x, or a type string called tmp – except we don’t have to know anything about the type T other than it will contain some form of data.

The template function means we can focus on the process, rather than the data itself.

Going to back to what Bjarne said (which I quoted in my previous post): Templates provide direct support for generic programming.

They are not about specifics, they are all about processing data without getting hung up on what that data is.

For comparison, this is what the code above would look like if we didn’t use a template function:

#include <iostream>
#include <string>

using namespace std;

//function definitions
void printdata(int);
void printdata(string);
void printdata(double);

int main()
{
    int x = 34567;
    string tmp = "hello";
    double y = 3.162;

    printdata(x);
    printdata(tmp);
    printdata(y);

    return 0;
}

//function declarations
void printdata(int number)
{
    cout << number << endl;
}

void printdata(string letters)
{
    cout << letters << endl;
}

void printdata(double fraction)
{
    cout << fraction << endl;
}

Can you see how we have to specify each individual function?

Not only that, but we’d have to add more code for every new data type that we wanted to use. The template version though, never needs more than one single declaration and definition.

That’s cool, but what does the compiler do with template source code? Doesn’t it just create all those functions anyway?

That’s exactly right, the compiler does create the functions, but the important thing is that there is no maintenance of this code, no potential for copy and paste errors, and no need to keep adjusting/adding functions every time your data type changes.

Also, the compiler will only create source for datatypes that are used.

This is important, so I’ll explain it again:

In the template example at the top, we call the template function with three different data types – int, string and double. The template function however, could also take another type, such as a char, or even a user defined class, or enum, or anything. However, the compiler won’t create functions for every single possible data type that you might use – how could it even know them all? Instead it only creates source code for the actual data types that are called in your program. If, for example, we deleted the call to print the string data, the compiler would no longer create a function to deal with string data.

This is also true for class templates – the compiler will only create source code once for each particular class type that you instantiate in your code.

So, in fact, template functions are efficient in that they only generate as much code as is needed for your program to execute successfully, no more, no less.



C++ Templates Made Easy

Templates.

Groan.

With their godawful syntax and impressive verbosity it’s no wonder we screw our faces up in distaste when we see them in code. ESPECIALLY when we’re debugging that code. Oh my. It’s enough to make you wish you were writing the software for musical birthday cards instead (does anyone actually do that?).

Anyway, I’ve wanted to talk about templates for a long time but the approach is a tricky one because even hearing the dreaded ‘T’ word is enough to make people run for the hills. I probably should have put that in angle brackets. The dreaded <T> word. Ha ha.

Anyway, here we go, let’s dive in together because there is safety in numbers.

Templates – made easy. I promise :-)

Read More »



Using Multiple Workspaces In Eclipse

If you do a lot of development work for lots of different programs or projects, you could try grouping them into separate workspaces in Eclipse.

It’s really easy to do and is a nice way to keep different types of projects together.

As you probably know, the default workspace is called ‘workspace’ and lives under your home folder on Linux. If you want to use additional workspaces, the steps below cover everything you need to know about using multiple workspaces:

 

1. Create a new folder

In your home directory, you need to create a new folder, which will be the location of your new workspace. You can call this folder anything: Coursework or 3DProjects, for example.

 

2. Switch to the new workspace in Eclipse

Open Eclipse and select File > Switch Workspace -> Other.

Browse to the location of the folder you created in step 1.

Then click OK.

Eclipse will close and re-open in the new workspace.

You can create new projects in here, have new settings, and it will all be completely separate from your old workspace.

 

3. Eclipse remembers all the workspaces you have opened

To switch back to the original one, select File -> Switch Workspace and you should see it listed in the box that pops out:

switchworkspace

 

4. You can edit the workspace list, and how many workspaces Eclipse remembers

If you delete a workspace completely, Eclipse may still store the data in its own cache.

To tidy-up the workspace list, you can edit the available workspaces under Window -> Preferences -> General -> Startup and Shutdown -> Workspaces.

Remove any that you no longer need, and set the number of workspaces you’d like Eclipse to store:

workspace-preferences

 

5. If you have missing projects in an Eclipse workspace, use the import existing projects option

If you’ve copied a workspace from another computer that already has Eclipse projects inside it, the first time you open the workspace you may have to import those projects so that you can see them.

Go to File -> Import -> General -> Exiting Projects into Workspace

Select the root directory, which by default is the current workspace folder – so just click okay.

You should see the projects from your workspace listed in the Projects window, with a tick in each box.

Ignore the message at the top that says Some projects cannot be imported because they already exist in the workspace.

Then click Finish.

Your projects should all appear in the Project Explorer window.

 

6. Set Eclipse to prompt for workspace on startup

When you switch to a workspace, Eclipse will take that as the default workspace going forward. So if you close everything down and come back tomorrow, Eclipse will open the last workspace you were using.

If you want to choose the workspace every time you start Eclipse, go to Window -> Preferences -> General -> Startup and Shutdown -> Workspaces and check the box at the top for ‘Prompt for workspace on startup’.



Fedora 21 Open Terminal From File Manager

If you use the command line a lot (like me!), then being able to switch quickly between the graphical file explorer and a terminal window in the same location is a fantastic timesaver.

On gnome this option isn’t available by default (as it is from KDE), but you can enable it by installing the nautilus-open-terminal package.

In a terminal window type:

sudo yum install nautilus-open-terminal

You may need to log out/in after doing this, although I didn’t need to on Fedora 21.

Once it has completed, if you right click in any ‘Files’ graphical window, you will see a new shortcut to ‘Open in terminal':

open-in-terminal

Super easy and super handy too!