593

Possible Duplicate:
C++ difference of keywords ‘typename’ and ‘class’ in templates

When defining a function template or class template in C++, one can write this:

template <class T> ...

or one can write this:

template <typename T> ...

Is there a good reason to prefer one over the other?


I accepted the most popular (and interesting) answer, but the real answer seems to be "No, there is no good reason to prefer one over the other."

  • They are equivalent (except as noted below).
  • Some people have reasons to always use typename.
  • Some people have reasons to always use class.
  • Some people have reasons to use both.
  • Some people don't care which one they use.

Note, however, that before C++17 in the case of template template parameters, use of class instead of typename was required. See user1428839's answer below. (But this particular case is not a matter of preference, it was a requirement of the language.)

Sasha
  • 2,636
  • 24
  • 43
Kristopher Johnson
  • 76,675
  • 54
  • 235
  • 299
  • 6
    I think in this case it might have been justified to pull all of the answers together and accept your own new answer instead of putting the answer in the question text. – Catskul Oct 05 '09 at 15:45
  • 10
    That's not really a duplicate. The one asks which is when preferable. The other asks for the differences. – Sebastian Mach Feb 28 '13 at 14:51
  • 23
    I don't see how this could possibly be a duplicate of a question asked more than one year later. – Marc.2377 Nov 20 '14 at 05:29
  • 1
    Just be consistent is all i'd say. Me me a typename boy, but it's up to you. – user4578093 Jun 29 '15 at 02:19
  • If the type I'm expecting is a default data type such as `int`, `float`, `double` etc., then normally I'll tend to use `typename`, on the other hand, if the template is expected to or has reason to accept classes, structures or user defined types then I'll tend to use `class`. This is only a self reference so that I can distinguish the purpose between two templates even if the keyword syntax is interchangeable 95% of the time. – Francis Cugler Feb 27 '16 at 04:08
  • 4
    this "possible duplicate" was asked in 2008. the "original" was asked in 2010. and they noticed in 2012. quality. – Puddle Jun 19 '19 at 09:36

10 Answers10

423

Stan Lippman talked about this here. I thought it was interesting.

Summary: Stroustrup originally used class to specify types in templates to avoid introducing a new keyword. Some in the committee worried that this overloading of the keyword led to confusion. Later, the committee introduced a new keyword typename to resolve syntactic ambiguity, and decided to let it also be used to specify template types to reduce confusion, but for backward compatibility, class kept its overloaded meaning.

Callum Watkins
  • 2,444
  • 2
  • 27
  • 42
itsmatt
  • 30,403
  • 10
  • 97
  • 160
  • 7
    And don't forget to read into the comments for whether there's a good reason to use "class" rather than "typename". – Michael Burr Oct 17 '08 at 22:06
  • 2
    REVIVAL! I don't find that article particularly clear, to be honest. in `T::A *obj;` the language, as far as I know, should parse the statement as a declaration because of the declaration rule: anything that looks like a declaration, even if it ambiguously looks like something else, should resolve into a declaration[0]. I also didn't find Bjarne Stroustrup clear about this. [0] The C++ Programming language 3e, Stroustrup, Appendix C.13.5, p. 856-858 – wilhelmtell Apr 08 '10 at 23:29
  • 1
    ... what's more, Stan Lippman says in the article "This sort of dilemna is not possible within generics – there is no way to safely verify that any T contains an A so that the runtime can safely construct an instance of the generic type". Since when are generic types instantiated at runtime? They are instantiated at compile-time, and for that exact reason without the `export` keyword we have to define templates in header files. And following that, one would expect the compiler to know everything about the instantiated generic -- including what `T::A` is, a type or an instance. – wilhelmtell Apr 08 '10 at 23:35
  • @wilhelmtell there is no such rule. The rule is only about expressions that have a functional cast as the first subexpression. In your example, if `T::A` is a type, the construct `T::A *obj` is actually ambiguous in the current Standard (as it turned out when I discussed it with the core group some weeks ago). However since everyone knows how it should be parsed, they don't make the Standard say how it should be parsed. Same with `f()` when `f` is a type (could be an invalid function call and could be a functional cast). – Johannes Schaub - litb Dec 27 '10 at 09:06
  • The reason of this confusion is the weird use of the "id-expression" non-terminal: Some parts of the Standard think the rule "id-expression" can't parse type names, while other parts think it can (sometimes only abusing this non-terminal since there isn't something else to use). The result is that ambiguity resolution and even the mere presence of ambiguities are more or less by-convention than being deduced from the Standard. So some paragraphs think, since `T::A` is a type, `T::A` can't be an id-expression and thus `T::A *obj` can't be a multiplication. But other paragraphs contradict this. – Johannes Schaub - litb Dec 27 '10 at 09:12
  • 1
    Even after the edit, this answer is underwhelming at best. – underscore_d Jan 14 '16 at 13:47
317

According to Scott Myers, Effective C++ (3rd ed.) item 42 (which must, of course, be the ultimate answer) - the difference is "nothing".

Advice is to use "class" if it is expected T will always be a class, with "typename" if other types (int, char* whatever) may be expected. Consider it a usage hint.

DarenW
  • 15,697
  • 7
  • 59
  • 96
155

As an addition to all above posts, the use of the class keyword is forced (up to and including C++14) when dealing with template template parameters, e.g.:

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };

In this example, typename Container would have generated a compiler error, something like this:

error: expected 'class' before 'Container'
Rakete1111
  • 42,521
  • 11
  • 108
  • 141
JorenHeit
  • 3,335
  • 2
  • 16
  • 26
49

I prefer to use typename because I'm not a fan of overloaded keywords (jeez - how many different meanings does static have for various different contexts?).

Michael Burr
  • 311,791
  • 49
  • 497
  • 724
  • 40
    Of course, typename is overloaded as well.... – James Curran Oct 17 '08 at 18:00
  • 8
    True, but it seems to be less confusingly overloaded - the other uses of `typename` are confusing not because of the overload as much as the situations where it's required are quite confusing. Other keyword overloads (`class` or `static`) seem to be active participants in the confusion. – Michael Burr Oct 17 '08 at 18:18
  • 5
    I have to agree with use of `typename` here -- use of class seems to overuse this keyword, particularly in instances of `template class Y { ...` – Billy ONeal Mar 19 '10 at 19:13
  • 3
    Personally, I find it easier to skim over code if it uses `typename` for template parameters. If I'm just skimming, looking for a class definition or declaration, I have to take a closer look each time I see `class`. Meanwhile, whenever I see `typename`, I automatically think, "Oh, it's either a template declaration or one of those wonky situations." Conversely, when skimming for templates, `class` might or might not be indicative of one, but you know `typename` can only be used when a template is afoot. – Justin Time - Reinstate Monica Jan 30 '16 at 21:46
17

There is a difference, and you should prefer class to typename.

But why?

typename is illegal for template template arguments, so to be consistent, you should use class:

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)
Community
  • 1
  • 1
user541686
  • 189,354
  • 112
  • 476
  • 821
9

In response to Mike B, I prefer to use 'class' as, within a template, 'typename' has an overloaded meaning, but 'class' does not. Take this checked integer type example:

template <class IntegerType>
class smart_integer {
public: 
    typedef integer_traits<Integer> traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t is a dependent name, so it requires 'typename' to preceed it so that the parser can recognize that larger_integer_t is a type. class, on the otherhand, has no such overloaded meaning.

That... or I'm just lazy at heart. I type 'class' far more often than 'typename', and thus find it much easier to type. Or it could be a sign that I write too much OO code.

Community
  • 1
  • 1
Aaron
  • 3,333
  • 21
  • 25
  • 9
    I don't consider that being overloaded. In both cases, typename does the same: signifying that it is followed by a type instead of a variable. – Leon Timmermans Oct 28 '08 at 18:24
  • 4
    But "typedef" is always followed by a type, so why is "typename" required here? I can understand it being required in something like `typename qwert::yuiop * asdfg;` if necessary to tell the parser that it's a pointer declaration and not a multiplication expression. But in a typedef there's no such ambiguity. – Stewart May 16 '11 at 10:59
  • 1
    You may be correct, I'm not sure if it is strictly required in my example. Your example is superior, as "qwerty::yuiop * asdfg;" might either be declaring a pointer variable, or invoking the multiplication operator. – Aaron May 18 '11 at 20:01
  • should that read `typedef integer_traits traits`? – obataku May 08 '16 at 23:49
9

Just pure history. Quote from Stan Lippman:

The reason for the two keywords is historical. In the original template specification, Stroustrup reused the existing class keyword to specify a type parameter rather than introduce a new keyword that might of course break existing programs. It wasn't that a new keyword wasn't considered -- just that it wasn't considered necessary given its potential disruption. And up until the ISO-C++ standard, this was the only way to declare a type parameter.

But one should use typename rather than class! See the link for more info, but think about the following code:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};
Olaf Mandel
  • 672
  • 6
  • 16
8

It doesn't matter at all, but class makes it look like T can only be a class, while it can of course be any type. So typename is more accurate. On the other hand, most people use class, so that is probably easier to read generally.

Frederik Slijkerman
  • 6,246
  • 23
  • 38
  • Well, anotherone could argue, that the possibility to use "class" makes it look like class can only be used for classes, and "typename" is thus restricted to primitive types. So this argument is kind of subjective ... – euphrat Sep 06 '13 at 00:08
  • One could make the point that every `class` name is a `typename`, but not every `typename` is a `class` name. If solely considering this, there are two logical approaches: 1) Always use `typename`, except when using template template parameters in pre-C++17 code, or 2) Use `class` if a parameter is explicitly supposed to be a user-defined type, or `typename` in other situations. Of course, the real world isn't as black-and-white as that, and there are also valid arguments for using `class` over `typename`, so it's best to use whichever one you or your team is/are most comfortable with. – Justin Time - Reinstate Monica Jun 29 '16 at 17:59
  • I personally find `typename` easier to parse, because its meaning always relates to templates. Others, on the other hand, find `class` easier to parse, with one reason being that there's inherent ambiguity in `typename`, due to it also being the keyword for using a type defined inside a templated type. So, this is primarily a subjective issue, except in the one case where the language explicitly requires one over the other. – Justin Time - Reinstate Monica Jun 29 '16 at 18:03
1

As far as I know, it doesn't matter which one you use. They're equivalent in the eyes of the compiler. Use whichever one you prefer. I normally use class.

Grant Limberg
  • 19,335
  • 10
  • 59
  • 84
-5

Extending DarenW's comment.

Once typename and class are not accepted to be very different, it might be still valid to be strict on their use. Use class only if is really a class, and typename when its a basic type, such as char.

These types are indeed also accepted instead of typename

template< char myc = '/' >

which would be in this case even superior to typename or class.

Think of "hintfullness" or intelligibility to other people. And actually consider that 3rd party software/scripts might try to use the code/information to guess what is happening with the template (consider swig).

muenalan
  • 500
  • 4
  • 7