0

When I was trying to finish a data structure assignment, in the implementation file there are some functions start with:

template <class ItemType>
ClassName<ItemType>::ClassName( )
{
}

I am now clear that the

<ItemType> 

is for replacement of a particular type (String, double, int,etc). But what is the function of the

template <class ItemType>

as every time before the function implementation we have to say it?

jsh6303
  • 2,010
  • 3
  • 24
  • 50
  • 1
    It's to indicate to the compiler that `` is for replacement by a particular type (as you said). How would the compiler know otherwise? – john Nov 14 '13 at 07:30
  • For scope inside a class you dont have to - outside you do (outside is where you need the ::) so - `template void x::f() { x tmp; ... }` you don't need to specify `x` when declaring `tmp` because it is understood – Glenn Teitelbaum Nov 14 '13 at 07:47
  • @Quirliom Eek, `cplusplus.com` is rife with errors and that page is no exception. I don't have a tutorial on hand but check [the book list](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?rq=1) – Potatoswatter Nov 14 '13 at 07:59

2 Answers2

2

It's to tell the compiler that the class or function is a template class/function, and what the name of the template argument is.

As for normal function argument, the name in the declaration doesn't have to be same as in the definition. So you can have e.g.

template<typename Foo>
struct Bar
{
    void f(int a);
};

template<typename Beer>
void Bar<Beer>::f(int flop)
{
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

It is part of how one defines nested template classes and functions, and their specializations outside of their containing classes:

#include <exception>

template<class yams_t>
class outer
{
public:

    template<class potatoes_t>
    class inner;
};

template<class yams_t>
template<class potatoes_t>
class outer<yams_t>::inner
{
public:

    template<typename result_t>
    result_t verb_my_noun();
};

template<class yams_t>        // yams_t is resolved first
template<class potatoes_t>    // potatoes_t is resolved next
template<typename result_t>   // result_t is resolved last
result_t outer<
    yams_t  // we want to parameterize outer<> first
    >::inner<
    potatoes_t    // then inner<>
    >::verb_my_noun()    // then verb_my_noun()
{
    return result_t(47);
}

template<>
class outer<float>
{
public:

    template<class potatoes_t>
    class inner;
};

template<>
class outer<float>::inner<float>
{
public:

    template<typename result_t>
    result_t verb_my_noun()
    {
        throw std::exception("You've been verbed!");
    }
};

template<>
class outer<float>::inner<double>
{
public:

    template<typename result_t>
    result_t verb_my_noun();
};

// As this is a full specialization of both
// outer<> and its inner class inner<>,
// we don't need two 'template<>'s above this.
//
// However, we still need a template<> for verb_my_noun()
template<typename result_t>
result_t outer<float>::inner<double>::verb_my_noun()
{
    return result_t();
}

Example:

int main(int argc, char **argv)
{
    outer<int>::inner<unsigned> good_thing;

    float x = good_thing.verb_my_noun<float>();

    // x is 47.0

    outer<float>::inner<float> bad_thing;

    // throws exception("You've been verbed!");
    float cant_see_me = bad_thing.verb_my_noun<float>();

    return 0;
}



Also note that you can do silly things like the following:

template<
    class alpha_t, // #1
    class beta_t,  // #2
    class gamma_t  // #3
>
class thing
{
    void frob();
};

template<
    class herp_t, // #1
    class derp_t, // #2
    class dorp_t  // #3
>
void thing<herp_t,derp_t,dorp_t>::frob()
{
}

Please do not actually do anything like the above. It is there for the sake of exposition, and in practice, it makes template code incredibly difficult to read.

defube
  • 2,395
  • 1
  • 22
  • 34