typename
| This article does not cite any references or sources. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (December 2009) |
"typename" is a keyword in the C++ programming language with two distinct uses related to templates. It is a synonym for "class" in template parameters, and it is used to specify that a dependent name in a template definition or declaration is a type.
A synonym for "class"
In C++'s generic programming feature known as "templates", typename can be used to introduce a template parameter:
<source lang="cpp">
// Define a generic function that returns the greater of its two arguments
template <typename T>
const T& max(const T& x, const T& y)
{
if (y < x) return x; return y;
} </source>
An alternative and semantically equivalent keyword in this scenario is "class":
<source lang="cpp"> // Define a generic function that returns the greater of its two arguments template <class T> const T& max(const T& x, const T& y) {
if (y < x) return x; return y;
} </source>
A method for indicating that a dependent name is a type
Consider this invalid code: <source lang="cpp"> template <typename T> void foo(const T& t) {
// declare a pointer to an object of type T::bar T::bar * p;
}
struct StructWithBarAsType {
typedef int bar;
};
int main() {
StructWithBarAsType x; foo(x);
} </source>
This code looks like it should compile, but it is incorrect because the compiler does not know if T::bar is a type or a value. The reason it doesn't know is that T::bar is a "template-parameter dependent name", or "dependent name" for short, and as such could represent anything named "bar" inside a type passed to foo(), which could include typedefs, enums, variables, etc.
To resolve this ambiguity, the C++ Language Standard declares:
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
In short, if the compiler can't tell if a dependent name is a value or a type, then it will assume that it is a value.
In our example, where T::bar is the dependent name, that means that rather than declaring a pointer to T::bar named "p", the line
T::bar * p;
will instead multiply the "value" T::bar times p (which is nowhere to be found) and throw away the result. The fact that in StructWithBarAsType the dependent bar is in fact a type does not help since foo() could be compiled long before StructWithBarAsType is seen. Furthermore, if there is also a class like:
<source lang="cpp"> struct StructWithBarAsValue {
int bar;
}; </source> then the compiler would be obliged to interpret the same template function in completely different ways.
The solution to this problem is to explicitly tell the compiler that T::bar is in fact a type. For this, the typename keyword is used:
<source lang="cpp">
template <typename T>
void foo(const T& t)
{
// declare a pointer to an object of type T::bar typename T::bar * p;
}</source>
Now the compiler knows for sure that T::bar is a type, and will correctly make p a pointer to an object of that type.
See also
- Argument dependent name lookup - another C++ name lookup rule
If you like SEOmastering Site, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...