Typename

Short description: C++ keyword

typename[1][2] is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.[3][4] In the original C++ compilers before the first ISO standard was completed, the `typename` keyword was not part of the C++ language and Bjarne Stroustrup used the `class` keyword for template arguments instead. While `typename` is now the preferred keyword, older source code may still use the `class` keyword instead (for example see the difference in source code examples between The Design and Evolution of C++ by Bjarne Stroustrup published in 1994 and the source code examples in The C++ Programming Language: Fourth Edition by Bjarne Stroustrup published in 2013).

## Contents

* 1 A synonym for class in template parameters
* 2 A method for indicating that a dependent name is a type
* 3 See also
* 4 References

## A synonym for `class` in template parameters

In C++'s generic programming feature known as "templates", `typename` can be used for introducing a template parameter:[3][4]

// Define a generic function that returns the greater of its two arguments
template <typename T>
nodiscard
const T& max(const T& x, const T& y) noexcept {
return y < x ? x : y;

An alternative and semantically equivalent keyword in this scenario is "`class`":

// Define a generic function that returns the greater of its two arguments
template <class T>
nodiscard
const T& max(const T& x, const T& y) noexcept {
return y < x ? x : y;

When using concepts, a means of constraining the generic type to satisfy some set of rules, the name of the concept replaces the keyword `typename`.

import std;

using std::is_base_of_v;
using std::vector;

class Player {
// ...

template <typename T>
concept ExtendsPlayer = is_base_of_v<Player, T>;

// T is required to be a type whose inheritance upper bound is Player,
// blocking any type that does not inherit from Player
template <ExtendsPlayer T>
void processListOfPlayers(vector<T> players) {
// ...

## A method for indicating that a dependent name is a type

Consider this invalid code:[5]

template <typename T>
void foo(const T& t) {
// declares a pointer to an object of type T::bar
T::Bar* p;  // error (see text)

struct UsesBar {
using Bar = int;

int main() {
UsesBar x;
foo(x);

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, which then 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` by `p` (which is nowhere to be found) and throw away the result. The fact that in `UsesBar` the dependent `Bar` is in fact a type does not help since `foo()` could be compiled long before `UsesBar` is seen. Furthermore, if there is also a class like:

struct HoldsBar {
int Bar;

then the compiler would be obliged to interpret the `T::Bar` in `foo()` as an access to data member `HoldsBar::Bar` when instantiated. But since `Bar` is not a static data member it will flag an error.

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:[3][4]

template <typename T>
void foo(const T& t) {
// declares a pointer to an object of type T::Bar
typename T::Bar* p;

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.

In C++20, required usage of the `typename` keyword was reduced.[6]

## See also

* Argument-dependent name lookup – another C++ name lookup rule

## References

1. ↑ Al Stevens (April 2003). "Underdocumented C++". Dr. Dobb's Journal: 72–76.
2. ↑ T. L. Veldhuizen (2013). "C++ templates are turing complete". https://web.archive.org/20060918135742/http://osl.iu.edu/~tveldhui/papers/2003/turing.pdf.
3. ↑ 3.0 3.1 3.2 "The typename keyword (C++ only)". IBM. http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_typename.htm. Retrieved 23 August 2013.
4. ↑ 4.0 4.1 4.2 "MSDN - typename". MSDN. http://msdn.microsoft.com/en-us/library/8y88s595.aspxtypename. Retrieved 23 August 2013.
5. ↑ "Dependent name lookup for C++ templates". February 6, 2012. https://eli.thegreenplace.net/2012/02/06/dependent-name-lookup-for-c-templates.
6. ↑ "Down with typename!". https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r3.html.

0.00

(0 votes)

Original source: https://en.wikipedia.org/wiki/Typename. Read more

|

Retrieved from "https://handwiki.org/wiki/index.php?title=Typename&oldid=4413523"