element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Code Exchange
  • Technologies
  • More
Code Exchange
Blog C++ Tutorial - Templates
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Code Exchange to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: oneleggedredcow
  • Date Created: 16 Apr 2013 11:32 PM Date Created
  • Views 1267 views
  • Likes 1 like
  • Comments 2 comments
  • coding
  • code_exchange
  • Code Exchange
  • programming
  • raspberry_pi
  • code
  • rpi
  • c++
  • learnc++
Related
Recommended

C++ Tutorial - Templates

oneleggedredcow
oneleggedredcow
16 Apr 2013

Introduction

In the previous tutorial, we used the STL (Standard Template Library) implementations of dynamic lists.  More specifically, we looked at the forward_list, the list, and the vector.  We showed how to use them and talked about which scenarios are best suited for which type of list.

 

In this tutorial, we are going to go over how the STL dynamic lists can store any type of data type. It does this through the use of templates.

Code

So, let’s jump into an example of writing a function to add two numbers together:

 

template <class T>

T Add(T a, T b)

{

return a + b;

}


The template command tells the compiler that you want the function to take in any data type.  You also give the data type a name, in this case we call it T. We give it a name so that it is easier to refer to it later.  So, now we declare the function using the new stand in data type called T.  We can treat this new type T as though it were a normal data type.

 

Now we can call our new function like this:

 

int main()

{

double d1 = 2.3;

double d2 = 3.4;

cout << Add(d1, d2) << endl;


 

int i1 = 4;

int i2 = 5;

cout << Add(i1, i2) << endl;


 

return 0;

}

 

What is exciting about this is that we wrote one function, and it was able to handle both int and double data types.  Without templates, we would have to write two functions to do this:

 

double Add(double a, double b)

{

return a + b;

}


 

int Add(int a, int b)

{

return a + b;

}

 

This can be very repetitive.  So, templates were created to save you from repeating the same code over and over with different input types.  Templates also work on classes:

 

template <class T>

class Complex

{

public:

T Real;

T Imag;


 

Complex(T real, T imag)

{

Real = real;

Imag = imag;

}

};

 

This allows you to create a class that can store any data type. In the case of a list, this can be a huge life saver.  No one wants to write the exact same code to create two lists, one that handles int and one that handles double!  It doesn’t matter what kind of object is being stored, we just want a way to store it.

 

Then you would create a variable of the class like this:

 

Complex<double> cmplxDbl(1.1, 2.2);

Complex<int> cmplxInt(3, 4);

 

This should look very familiar to the way that the STL classes were created in the last tutorial.

 

What is really going on behind the scenes is that the compiler is generating the templated methods and classes for you.  So, the compiler sees a method called Add that has a template parameter of T.  It then waits to see how the Add method is used. When it comes across the first call to Add with two doubles as the arguments, it generates a method for us that has two doubles as input arguments.  Much like the code sample above of the function that we would have written without templates.  Then when it comes across the call to Add with two ints as input arguments, it generates a method for that.  This means that the compiler is doing the repetitive work of creating two methods with the same logic but different types for us. The compiler also just creates the functions that we need, meaning that it doesn’t create one for say floats until we need it.

Buyer Beware

The template’s ability to take in any data type is a double edged sword though.  Take this for example:

 

template <class T>

T Mult(T a, T b)

{

return a * b;

}


 

class Complex

{

public:

double Real;

double Imag;


 

Complex(double real, double imag)

{

Real = real;

Imag = imag;

}

};


 

class Matrix2x2

{

public:

double M00;

double M01;

double M10;

double M11;


 

Matrix2x2(double m00, double m01, double m10, double m11)

{

M00 = m00;

M01 = m01;

M10 = m10;

M11 = m11;

}

};


 

int main()

{

Complex c1(1.1, 2.2);

Complex c2(3.3, 4.4);

Complex c3 = Mult(c1, c2);

      

Matrix2x2 m1(1, 2, 3, 4);

Matrix2x2 m2(2, 4, 6, 8);

Matrix2x2 m3 = Mult(m1, m2);


 

return 0;

}

 

At first glance, it looks harmless enough.  We know how to multiply together two complex numbers or two 2x2 matrices.  No problem. Well, it won’t compile.  You’ll get an error message saying that it doesn’t know how to apply the * operator to those objects.  If we think about it the complier is right.  We just happened to call our class Complex and give it two variables named Real and Imag.  How is the compiler supposed to tell this class from any other class?

 

The 2x2 matrix class is slightly more interesting because there are two ways to multiply together matrices that makes sense.  We could either do matrix multiplication or we could multiply them together element-wise.  Even if the compiler was able to discern that it was a matrix, it still wouldn’t be able to tell how you wanted them multiplied together.

 

So, that’s the big benefit and the big problem: any data type can be passed in.  This can make it difficult to design a class or method that gets some work done, but is flexible enough to handle a wide variety of input data types.  As we have seen above, even something as simple as addition or multiplication is difficult to make work over a wide range of inputs.

Summary

In this tutorial, we talked about templates, which are a way to write a function or class once and then have the compiler create versions of it for every data type that you want passed in.

 

In the next tutorial, we are going to talk about inheritance. Inheritance is when one class inherits all of the properties and methods of its parent.  This is a very powerful tool to help reduce the number of lines of code and to make the code more clear.  It also can help with the template problem we had above.  Instead of using a template, which means that any data type can be passed in, we can use a class, which means that only that type or classes that inherit from that class can be passed in.   We can use this as a way to make our function work on many classes, but at the same time rest assured that they have some minimal set of properties and methods, so that they can work properly.

 

If you have any questions or comments about what was covered here, post them to the comments.  I watch them closely and will respond and try to help you out.

Tutorial Index

01 - Hello Raspberry Pi

02 - Reading User Input

03 - If Statement

04 - For Loops

05 - While Loops

06 - Functions

07 - Data Types

08 - Arrays

09 - Structures

10 - Classes

11 - Pointers

12 - Dynamic Arrays

13 - Linked List

14 - Linked List Operations

15 - STL List/Vector

16 - Templates

17 - Inheritance

18 - File I/O

19 - Strings

20 - Constants

21 - Hash Tables

  • Sign in to reply
  • raspgraph
    raspgraph over 8 years ago

    I have followed your program and think I have this right as you described in your text.

    int main()

    {

      double d1 = 2.3;

      double d2 = 3.4;

      cout << Add(d1, d2) << endl;

     

     

     

      int i1 = 4;

      int i2 = 5;

      cout << Add(i1, i2) << endl;

     

     

     

      return 0;

    }

    template <class T>

    T Add(T a, T b)

    {

      return a + b;

    }

     

    BUT the template doesn't seem to relate to main.

    following errors occur when compiling within raspberry pi terminal

     

    pi@raspberrypi:~/Desktop $ g++ -std=c++0x 05_template.cpp -o05_template

     

    05_template.cpp: In function ‘int main()’:

    05_template.cpp:5:2: error: ‘cout’ was not declared in this scope

      cout << Add(d1, d2) << endl;

      ^

    05_template.cpp:5:20: error: ‘Add’ was not declared in this scope

      cout << Add(d1, d2) << endl;

                        ^

    05_template.cpp:5:25: error: ‘endl’ was not declared in this scope

      cout << Add(d1, d2) << endl;

     

     

    I'm obviously missing something in the tutorial but can't quite see it

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 10 years ago

    Very nice.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube