Thread: Need help understanding Templates

  1. #1
    Registered User
    Join Date
    Jul 2005
    Posts
    45

    Need help understanding Templates

    I went through my book's chapter about function templates and I'm trying to make sure I understand this correctly.
    There’s an example in the book so I tried to do a program using templates to create a program on absolute values to see If I get it, but I’m getting a bunch of errors so obviously I didn’t.

    Here’s what I did:
    Code:
    #include<iostream>
    
    using namespace std;
    
    
    
    template <class Value>
    void printAbsValue()
    {
    	if (Value<0)
    	{
    		cout<<"The absolute value of "<<Value<<" is "<<(-Value)<<endl;
    	}
    	else
    	{
    		cout<<"The absolute value of "<<Value<<" is "<<Value<<endl;
    	}
    }
    
    
    int main()
    {
    	const int aValue=10;
    	const float bValue=10.4;
    	const double cValue=1.5;
    
    	int a[aValue]=-23;
        float b[bValue]=-23.55;
    	double c[cValue]=-2.4;
    
    	printAbsValue(a, aValue);
    	printAbsValue(b, bValue);
    	printAbsValue(c, cValue);
    	
    	return 0;
    }
    Here are the errors I’m getting:
    Code:
    .cpp(28) : warning C4305: 'initializing' : truncation from 'double' to 'const float'
    .cpp(31) : error C2440: 'initializing' : cannot convert from 'int' to 'int [10]'
            There are no conversions to array types, although there are conversions to references or pointers to arrays
    .cpp(32) : error C2057: expected constant expression
    .cpp(32) : error C2466: cannot allocate an array of constant size 0
    .cpp(32) : error C2440: 'initializing' : cannot convert from 'double' to 'float []'
            There are no conversions to array types, although there are conversions to references or pointers to arrays
    .cpp(33) : error C2057: expected constant expression
    .cpp(33) : error C2466: cannot allocate an array of constant size 0
    .cpp(33) : error C2440: 'initializing' : cannot convert from 'double' to 'double []'
            There are no conversions to array types, although there are conversions to references or pointers to arrays
    .cpp(35) : error C2780: 'void printAbsValue(void)' : expects 0 arguments - 2 provided
    .cpp(12) : see declaration of 'printAbsValue'
    .cpp(36) : error C2780: 'void printAbsValue(void)' : expects 0 arguments - 2 provided
    .cpp(12) : see declaration of 'printAbsValue'
    .cpp(37) : error C2780: 'void printAbsValue(void)' : expects 0 arguments - 2 provided
    .cpp(12) : see declaration of 'printAbsValue'
    Can anyone tell me if I understand this concept correctly and point me in the right direction to understand this.
    Thanks.

  2. #2
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    you're close enough. I think you have the general idea right, but just not the syntax (which can be pretty scary at first!!)

    ok in your function you have
    Code:
    template <class Value>
    void printAbsValue()
    {
    //snip
    }
    which should be
    Code:
    template <typename Value> // 1
    void printAbsValue(Value v) // 2
    {
    // 3
    	if (v<0)
    	{
    		cout<<"The absolute value of "<<v<<" is "<<(-v)<<endl;
    	}
    	else
    	{
    		cout<<"The absolute value of "<<v<<" is "<<v<<endl;
    	}
    }
    1. this is a nit, but you should really use typename instead of class.
    2. ok you've declared the template parameter, but you still need to pass an instance of the templated type to the function
    3. use the instance of the templated type in the body of the function

    ok now for you client code
    Code:
    int a[aValue]=-23;
    float b[bValue]=-23.55;
    double c[cValue]=-2.4;
    no idea what you thought you were doing here but it's not what you want. (you're actually declaring an array here)

    Code:
    printAbsValue(a, aValue);
    printAbsValue(b, bValue);
    printAbsValue(c, cValue);
    ok again you're close here, but not quite
    syntax is actually
    Code:
    printAbsValue<int>(a);
    printAbsValue<float>(b);
    printAbsValue<double>(c);
    
    // but a good compiler will deduce the arguements so it's just
    printAbsValue(a);
    printAbsValue(b);
    printAbsValue(c);
    hope that helps
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  3. #3
    Registered User
    Join Date
    Jul 2005
    Posts
    45
    ChaosEngine
    Thanks It should help big time.
    I'll work on this and let you know how it goes.

    Thanks again.

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Hi,

    You are treating the template parameter incorrectly: you are using it as if it were a quantity. For instance, you are trying to cout Value as if it were a number. That is somewhat understandable since you chose the misleading name Value. However, the template parameter is a type, e.g. int, double, float--not a value; and you can't display a type. You wouldn't do this:

    cout<<int<<endl; //error

    If you want an easy way to write a template function, try this: write the function for an int type, e.g.
    Code:
    void printAbsValue(int theNumber)
    {
    	if (theNumber <0)
    	{
    		cout<<"The absolute value of "<<theNumber<<" is "<<-theNumber<<endl;
    	}
    	else
    	{
    		cout<<"The absolute value of "<<theNumber<<" is "<<theNumber<<endl;
    	}
    }
    Next, the whole reason you would want a template function is so that it will work for different types--not just ints. So, make the type a variable by templating the function. To do that, replace int with T (which stands for Type) everywhere you want the int type to be a variable:
    Code:
    template<typename T>
    void printAbsValue(T theNumber)
    {
    	if (theNumber <0)
    	{
    		cout<<"The absolute value of "<<theNumber<<" is "<<-theNumber<<endl;
    	}
    	else
    	{
    		cout<<"The absolute value of "<<theNumber<<" is "<<theNumber<<endl;
    	}
    }
    When you call the template function with a certain type, e.g.

    printAbsValue(10.35);

    the compiler deduces what type is required depending on what type of argument you use--in this case a double--and it creates a version of the function by substituting double everywhere T appears.

    Note that generally you can't just use the "search and replace" facilitites of a text editor to replace int with T everywhere int appears in your function. There are some int types in a function you may not want to vary, like a loop variable:
    Code:
    for(int i = 0; i < 10; i++)
    {
             ...
             ...
    }
    You wouldn't want i's type to vary with the template parameter, so in that case don't replace it with T when converting the funtion into a template function.
    Last edited by 7stud; 11-02-2005 at 05:45 AM.

  5. #5
    Registered User
    Join Date
    Jul 2005
    Posts
    45
    Thank to both of you I Think I've got it. I think I'm understanding the template concept much better.

    I'll try to do another "little" program using template to make sure.

    Thanks so much.

  6. #6
    Registered User
    Join Date
    Nov 2005
    Posts
    85
    wats the difference with using template<typename T> instead of template<class T> because this is what i am used to using

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    There is no difference. class is the old-style way of doing it.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by dwks
    There is no difference. class is the old-style way of doing it.
    yep, it's purely a style-thing, but I prefer typename as class implies it must be a class (as opposed to a pod).
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Some very old compilers only support class. I generally use typename, too, though.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Questions about Templates
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2005, 12:22 AM
  2. understanding recursive functions
    By houler in forum C Programming
    Replies: 7
    Last Post: 12-09-2004, 12:56 PM
  3. templates and inheritance problem
    By kuhnmi in forum C++ Programming
    Replies: 4
    Last Post: 06-14-2004, 02:46 AM
  4. When and when not to use templates
    By *ClownPimp* in forum C++ Programming
    Replies: 7
    Last Post: 07-20-2003, 09:36 AM