Use 'class' or 'typename' for template parameters?
C++TemplatesC++ Problem Overview
> 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.)
C++ Solutions
Solution 1 - C++
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.
Solution 2 - C++
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.
Solution 3 - C++
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'
Solution 4 - C++
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?).
Solution 5 - C++
class
to typename
.
There is a difference, and you should prefer 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 { }; // :)
Solution 6 - C++
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.
Solution 7 - C++
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 ...
};
Solution 8 - C++
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.
Solution 9 - C++
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.
Solution 10 - C++
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).