1

I have learned that data structures can be created using templates in the following way:

template<typename T>
struct X {
   T weight;
   int age;
};

The functions can also use templates in the following way:

template <class T>
T func_name(int age, T human) {
    something_here;
}

One of the difference s is that in the first case we use typename while in the second case we use class.

I found code that contains the following:

template<typename S, typename T>
bool is_null(const row<T>& r)

So, what I cannot understand is why we use typename (and not class) in combination with functions. Shouldn't we use class?

Roman
  • 124,451
  • 167
  • 349
  • 456
  • You may find [this question](http://stackoverflow.com/questions/213121/use-class-or-typename-for-template-parameters) relevant to yours. Or perhaps [this question](http://stackoverflow.com/questions/2023977/c-difference-of-keywords-typename-and-class-in-templates) – WhozCraig Mar 11 '13 at 16:03

4 Answers4

3

In this context, there is no technical difference between the keyword typename and the keyword class. It's just a matter of style. The meaning of your first two code examples would not change one bit if they started with template<class T> struct X and template <typename T> T func_name(int age, T human). (I tend to use class when I mean to imply the template parameter should be a class, and not something like int.)

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • 2
    Are `typename` and `class` always interchangeable or only in this context? – Roman Mar 11 '13 at 16:02
  • Only when declaring a template parameter. – aschepler Mar 11 '13 at 16:02
  • @Roman, you can't declare a class using the `typename` keyword (an obvious difference); you can't also [disambiguate dependent types](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords/613132#613132) using the `class` keyword. But when declaring type parameters of a template, `class` and `typename` are interchangeable. – ulidtko Mar 11 '13 at 16:05
  • 2
    @Roman When it comes to declaring template parameters the two keywords are always interchangeable, except for [template template parameters](http://stackoverflow.com/a/11311432/241631) when you must use `class` – Praetorian Mar 11 '13 at 16:06
0

When template was first introduced, it ONLY allowed the existing keyword class as an indicator "this is a template argument". Since this becomes rather daft when the template argument isn't actually a class (a function pointer, integer type, or some other "not a class" type), the typename was introduced to make it more clear that template<typename T> struct something { T x; }; allows something<int> a; as well as something<name_of_class> a;.

For all intents and purposes, class and typename in the case of template parameters is interchangeable, and it's just a matter of style which you choose to do [most people probably prefer if you stick to one, not mixing the two - or, perhaps use class when the type HAS TO be a class, and typename when it can be "any" type].

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

In the context of template parameter definitions the keywords typename and class are synonymous.

Just about everyone has a convention they tend to stick with. I personally prefer to always use class here and reserve the typename keyword for its other use.

The other use for typename is to disambiguate a dependent type in a template definition or declaration.

Here is an example from wikipedia:

template <typename T>
void foo(const T& t)
{
   // declares a pointer to an object of type T::bar
   T::bar * p;
}

struct StructWithBarAsType {
   typedef int bar;
};

int main() {
   StructWithBarAsType x;
   foo(x);
}

If you look closely you will notice in the line T::bar * p;, bar is dependent on a template parameter T which is ambiguous to the compiler as bar can be either a type or a value depending on the context of the type T used for instantiating the template. The default is to treat bar as a value so the meaning would be to multiply T::bar by p which is not what we want.

The solution is to qualify the dependent type with the typename keyword.

typename T::bar * p;

This alerts the compiler to the fact that we intend to treat bar as a type.

Matthew Sanders
  • 4,875
  • 26
  • 45
0

There's only one spot where they differ (when declaring template parameters), and that is when using template-templates.

The following is well-defined C++

template <template <typename> class TT> struct example_one {};

while this is not:

template <template <typename> typename TT> struct example_two {};

Since it seems like you're just starting out with C++/templates, this corner case won't concern you for a while :-) Aside from the above, class template, function template, it doesn't matter: typename and class are synonymous.

bstamour
  • 7,746
  • 1
  • 26
  • 39