tags:

views:

5769

answers:

9

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.
  • 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.
+1  A: 

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
+17  A: 

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

itsmatt
Thanks for the link - I also found it interesting (but not surprising).
Michael Burr
And don't forget to read into the comments for whether there's a good reason to use "class" rather than "typename".
Michael Burr
I think defacto StackOverflow ettiquette is to offer a few line summary if you are going to defer to a "look here".
Catskul
I wrote this response nearly a year ago, about a month after the site went public. There was hardly a defacto anything at that point. Point taken, though.
itsmatt
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
... 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
+29  A: 

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
I like the concept of the hint factor. I think I will start using that.
Martin York
+7  A: 

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
Of course, typename is overloaded as well....
James Curran
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
I have to agree with use of `typename` here -- use of class seems to overuse this keyword, particularly in instances of `template<class X> class Y { ...`
Billy ONeal
+1  A: 

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
+2  A: 

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.

Aaron
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
A: 

Steve Dewhurst thinks that these two words have the same meaning in current context. So do I

chester89
A: 

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
A: 

Just pure history: "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...." Stan Lippman. [Source: http://blogs.msdn.com/slippman/archive/2004/08/11/212768.aspx]

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 ...
// ...
};

lmchdev