For more information, see Templates and Name Resolution. It is not allowed in the base class list, unless as a template argument to a template base class. The typename keyword can also be used in place of class in template parameter lists. For example, the following statements are semantically equivalent:. Templates Keywords. Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.
A template parameter of the form class Foo is not an unnamed non-type template parameter of type Foo , even if otherwise class Foo is an elaborated type specifier and class Foo x ; declares x to be of type Foo. If the deduced type is not permitted for a non-type template parameter, the program is ill-formed.
For non-type template parameter packs whose type uses a placeholder type, the type is independently deduced for each template argument and need not match:. An identifier that names a non-type template parameter of class type T denotes a static storage duration object of type const T , called a template parameter object , whose value is that of the corresponding template argument after it has been converted to the type of the template parameter.
All such template parameters in the program of the same type with the same value denote the same template parameter object. A template parameter object shall have constant destruction. In the body of the template declaration, the name of a type parameter is a typedef-name which aliases the type supplied when the template is instantiated.
Each constrained parameter P whose type-constraint is Q designating the concept C introduces a constraint-expression E according to the following rules:. In the body of the template declaration, the name of this parameter is a template-name and needs arguments to be instantiated. The name of a template parameter is not allowed to be redeclared within its scope including nested scopes. A template parameter is not allowed to have the same name as the template name. In the definition of a member of a class template that appears outside of the class template definition, the name of a member of the class template hides the name of a template parameter of any enclosing class templates, but not a template parameter of the member if the member is a class or function template.
In the definition of a member of a class template that appears outside of the namespace containing the class template definition, the name of a template parameter hides the name of a member of this namespace. In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each non- dependent base class, if the name of the base class or the name of a member of the base class is the same as the name of a template parameter, the base class name or member name hides the template parameter name.
In order for a template to be instantiated, every template parameter type, non-type, or template must be replaced by a corresponding template argument. For function templates , the arguments are explicitly provided, deduced from the context , or defaulted. If an argument can be interpreted as both a type-id and an expression, it is always interpreted as a type-id, even if the corresponding template parameter is non-type:.
The following limitations apply when instantiating templates that have non-type template parameters:. In particular, this implies that string literals, addresses of array elements, and addresses of non-static members cannot be used as template arguments to instantiate templates whose corresponding non-type template parameters are pointers to objects. The template argument that can be used with a non-type template parameter can be any converted constant expression of the type of the template parameter.
A template argument for a type template parameter must be a type-id , which may name an incomplete type:. A template argument for a template template parameter must be an id-expression which names a class template or a template alias. When the argument is a class template, only the primary template is considered when matching the parameter. The partial specializations, if any, are only considered when a specialization based on this template template parameter happens to be instantiated.
If P 's parameter list includes a parameter pack , zero or more template parameters or parameter packs from A 's template parameter list are matched by it. Having said that, there are specific cases where there is a difference between typename and class. The first one is in the case of dependent types. I'm sure that there are other cases that I've missed, but the bottom line is: these two keywords are not equivalent, and these are some common cases where you need to use one or the other. Active 1 year, 1 month ago.
Viewed k times. Improve this question. 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. That's not really a duplicate. The one asks which is when preferable. The other asks for the differences.
I don't see how this could possibly be a duplicate of a question asked more than one year later. Just be consistent is all i'd say. Me me a typename boy, but it's up to you. Show 1 more comment. Active Oldest Votes. Improve this answer. Callum Watkins 2, 2 2 gold badges 29 29 silver badges 44 44 bronze badges. And don't forget to read into the comments for whether there's a good reason to use "class" rather than "typename".
I don't find that article particularly clear, to be honest. I also didn't find Bjarne Stroustrup clear about this. 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.
The rule is only about expressions that have a functional cast as the first subexpression. 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. Even after the edit, this answer is underwhelming at best. DarenW DarenW I like the concept of the hint factor.
I think I will start using that.
0コメント