Question

Dependent Names, typename, and template in C++ Templates

cpptemplatestypenamec++-faqdependent-name

Question

In C++ templates, when and why do you need to write typename and template for dependent names?

What exactly is a dependent name?

For example, consider this code:

template <typename T, typename Tail> // Tail will also be a UnionNode.
struct UnionNode : public Tail {
    template <typename U>
    struct inUnion {
        // Where should typename/template be added here?
        typedef Tail::inUnion<U> dummy;
    };

    template <>
    struct inUnion<T> { };
};

template <typename T> // For the last node Tn.
struct UnionNode<T, void> {
    template <typename U>
    struct inUnion; // intentionally not defined

    template <>
    struct inUnion<T> { };
};

The issue is with this line:

typedef Tail::inUnion<U> dummy;

It seems that inUnion is a dependent name, so the compiler cannot know immediately what it refers to. I understand that template can be used to tell the compiler that inUnion is a template, but where exactly should it go?

Also, if template is used, does that automatically mean inUnion<U> is treated as a type rather than a function or something else?

Short Answer

By the end of this page, you will understand what dependent names are in C++, why the compiler sometimes needs extra help inside templates, and exactly when to use the typename and template keywords. You will also see how to fix expressions like Tail::inUnion<U> correctly and learn the common rules developers use in real template code.

Concept

In C++, templates are parsed in two phases:

  • Phase 1: the compiler parses the template before knowing the actual template arguments.
  • Phase 2: the compiler instantiates the template later, when real types are substituted.

Because of this, some names inside a template depend on a template parameter and cannot be fully understood during the first phase. These are called dependent names.

A name is dependent if its meaning depends on a template parameter. For example:

Tail::inUnion<U>

Here, Tail is a template parameter, so the compiler does not yet know what members Tail has. That means:

  • it does not know whether inUnion is a type, function, variable, or template
  • it cannot safely parse <U> as template arguments unless you tell it to

This is why C++ provides two disambiguation keywords:

  • typename tells the compiler: this dependent qualified name is a type
  • template tells the compiler: this dependent qualified name is a template

For your example, the correct form is:

typedef typename Tail::template inUnion<U> dummy;

Why both?

  • Tail::... is dependent because Tail is unknown at first parse time.
  • inUnion is a member template, so the compiler needs template before inUnion<U>.
  • The whole Tail::template inUnion<U> names a type, so typename is also required.

This matters in real programming because template-heavy C++ code often uses nested types, member templates, iterators, traits, allocators, policy classes, and metaprogramming utilities. Understanding these rules makes template code readable, correct, and portable across compilers.

Mental Model

Think of the compiler as reading a sentence with missing dictionary entries.

If it sees this:

Tail::inUnion<U>

it thinks:

  • “I do not know what Tail is yet.”
  • “So I do not know what inUnion means here.”
  • “That <U> might be template arguments... or it might be a less-than operator.”
  • “I also do not know whether the whole thing is a type.”

So you must label it clearly:

  • template = “parse the following name as a template”
  • typename = “treat the result as a type”

A simple analogy:

  • template is like saying: this is a generic blueprint
  • typename is like saying: the thing produced here is a type name

Without those labels, the compiler refuses to guess in dependent contexts.

Take Quiz

Syntax and Examples

Core rule

When you refer to a member template through a dependent type, write:

typename DependentType::template MemberTemplate<Args...>

When you refer to a nested type through a dependent type, write:

typename DependentType::NestedType

Your example fixed

template <typename T, typename Tail>
struct UnionNode : public Tail {
    template <typename U>
    struct inUnion {
        typedef typename Tail::template inUnion<U> dummy;
    };
};

This says:

  • Tail::... depends on Tail
  • inUnion is a template
  • inUnion<U> is a type

Example: dependent nested type

template <typename Container>
void printFirst(const Container& c) {
    typename Container::value_type x = *c.begin();
}

Why typename?

Because Container::value_type depends on Container, and the compiler does not know yet that value_type is a type.

Example: dependent member template call

template <typename T>
struct Wrapper {
    template <typename U>
    struct Rebind {
        using type = U;
    };
};

template <typename X>
void example() {
    typename X::template Rebind<int>::type value = 42;
}

Here:

  • X::template Rebind<int> uses template because Rebind is a member template of dependent type X
  • typename is needed because X::template Rebind<int>::type is a dependent type

Important note

Using template does not automatically mean the final expression is a type.

For example:

obj.template func<int>();

This uses template because func is a dependent member template, but this is a function call, not a type.

So:

  • template means “this name is a template”
  • typename means “this dependent qualified expression names a type”

Step by Step Execution

Consider this example:

template <typename Tail>
struct Node {
    template <typename U>
    struct inner {
        using type = U;
    };

    template <typename U>
    void test() {
        typename Tail::template inner<U> value;
    }
};

Step-by-step

  1. The compiler starts parsing Node<Tail>.
  2. It sees Tail::template inner<U> inside test().
  3. Tail is a template parameter, so the compiler does not know its real type yet.
  4. Therefore, Tail::inner is a dependent name.
  5. Without help, the compiler cannot know whether inner is:
    • a type
    • a static member
    • a function
    • a template
  6. The template keyword tells the compiler that inner is a template.
  7. The typename keyword tells the compiler that Tail::template inner<U> names a type.
  8. Now the declaration is valid.

What happens if you omit them?

Broken version:

template <typename Tail>
struct Node {
    template <typename U>
    void test() {
        Tail::inner<U> value;
    }
};

Problems:

  • the compiler may not parse <U> as template arguments
  • it does not know whether Tail::inner<U> is a type

Correct version:

template <typename Tail>
struct Node {
    template <typename U>
    void test() {
        typename Tail::template inner<U> value;
    }
};

Real World Use Cases

Dependent names appear often in real C++ code, especially in generic libraries.

1. Standard-library style generic code

template <typename Container>
void process(const Container& c) {
    typename Container::const_iterator it = c.begin();
}

Used when writing functions that work with many container types.

2. Traits and type transformations

template <typename Traits>
using value_type_t = typename Traits::value_type;

Common in type traits, allocators, iterators, and metaprogramming helpers.

3. Rebinding or nested templates

template <typename Alloc>
using int_alloc = typename Alloc::template rebind<int>::other;

Older allocator patterns and some generic libraries use this style.

4. CRTP and policy-based design

template <typename Policy>
struct Engine : Policy {
    void run() {
        typename Policy::config cfg;
    }
};

Useful when behavior or configuration comes from template parameters.

5. Generic member template calls

template <typename T>
void call(T& obj) {
    obj.template handle<int>();
}

This appears when a generic object has member templates and its concrete type is not known yet.

Take Quiz

Real Codebase Usage

In real projects, developers usually encounter these rules in a few repeatable patterns.

Guarding dependent types with aliases

Instead of repeatedly writing long dependent names, developers often create aliases:

template <typename Tail>
struct Node {
    template <typename U>
    using inner_t = typename Tail::template inner<U>;
};

This improves readability and reduces mistakes.

Validation through traits

Template code often checks whether a nested type or member template exists:

template <typename T>
using value_type_t = typename T::value_type;

This is common in generic utilities and library internals.

Early clarification in complex declarations

When a declaration is hard to read, developers put the type into a using declaration first:

template <typename Tail>
struct Node {
    template <typename U>
    void f() {
        using inner_type = typename Tail::template inner<U>;
        inner_type x;
    }
};

Error handling through clearer template structure

Compilers can produce confusing template errors. A common practice is to:

  • break long dependent expressions into smaller aliases
  • use using instead of old-style typedef
  • keep nested template references localized

Generic APIs and configuration types

Many libraries expose nested types such as:

  • value_type
  • iterator
  • const_iterator
  • type
  • rebind<U>

Whenever these are reached through a template parameter, typename and sometimes template are part of normal code.

Common Mistakes

1. Forgetting typename for a dependent type

Broken code:

template <typename T>
void f() {
    T::value_type x;
}

Correct:

template <typename T>
void f() {
    typename T::value_type x;
}

Why: T::value_type depends on T, so the compiler needs to be told that it is a type.

2. Forgetting template for a dependent member template

Broken code:

template <typename T>
void f() {
    typename T::rebind<int>::other x;
}

Correct:

template <typename T>
void f() {
    typename T::template rebind<int>::other x;
}

Why: rebind is a template member of dependent type T.

3. Thinking template implies typename

Broken assumption:

template <typename T>
void f() {
    T::template rebind<int> x;
}

This may still need typename if the expression names a type:

template <typename T>
void f() {
    typename T::template rebind<int> x;
}

template and typename solve different problems.

4. Using typename where it is not allowed or needed

Example:

template <typename T>
struct S : T::Base {
};

Base-class lists have their own parsing rules. You do not always write typename everywhere you see a dependent name.

A simpler rule for beginners:

  • in declarations, if a dependent qualified name is a type, you usually need typename
  • if it is also a template, you may need template too

5. Confusing type names with function calls

obj.template foo<int>();

This uses template, but not typename, because this is a function call, not a type declaration.

6. Blaming the wrong token

In code like this:

typedef Tail::inUnion<U> dummy;

both issues exist:

  • the compiler does not know inUnion is a template
  • the compiler does not know the full name is a type

So the fix is:

typedef typename Tail::template inUnion<U> dummy;

Comparisons

SituationExampleNeed typename?Need template?Why
Dependent nested typeT::value_typeYesNoIt is a type, but not a template
Dependent member template naming a typeT::rebind<int>YesYesIt is both a template and a type
Dependent member template function callobj.foo<int>()NoYes, as obj.template foo<int>()It is a template call, not a type
Non-dependent nested typestd::vector<int>::value_typeNoNoCompiler already knows what it is
Non-dependent class templatestd::vector<int>NoNoNo ambiguity from a template parameter

typename vs template

KeywordPurposeExample
typenameSays a dependent qualified name is a typetypename T::value_type
templateSays a dependent qualified name is a templateT::template rebind<int>

Old-style typedef vs using

StyleExampleNotes
typedeftypedef typename T::template rebind<int> type;Works, but harder to read
usingusing type = typename T::template rebind<int>;Usually clearer in modern C++
Take Quiz

Cheat Sheet

Quick rules

  • A dependent name is a name whose meaning depends on a template parameter.
  • Use typename when a dependent qualified name refers to a type.
  • Use template when a dependent qualified name refers to a template.
  • Sometimes you need both.

Common patterns

typename T::value_type
typename T::template rebind<int>
obj.template func<int>()

Your case

typedef typename Tail::template inUnion<U> dummy;

Meaning of each keyword

  • typename => “this is a type”
  • template => “this is a template”

When typename is not needed

  • For non-dependent names
  • In some special syntactic contexts
  • For function calls like:
obj.template run<int>();

Safe beginner rule

If you see Something::Other inside a template and Something depends on a template parameter:

  1. If Other is a type, add typename
  2. If Other is a template used with <...>, add template
  3. If both are true, use both

Readability tip

Prefer using in modern C++:

using dummy = typename Tail::template inUnion<U>;

FAQ

What is a dependent name in C++?

A dependent name is a name whose meaning depends on a template parameter. For example, T::value_type depends on what T actually is.

Why does C++ need typename?

Because when parsing a template, the compiler cannot always know whether a dependent qualified name refers to a type. typename removes that ambiguity.

Why does C++ need the template keyword?

Because the compiler cannot always tell whether a dependent member name followed by <...> is a template or something else. template tells it to parse the name as a template.

Do I always need both typename and template?

No. You use:

  • only typename for dependent types that are not templates
  • only template for dependent template function calls
  • both when a dependent member template names a type

What is the correct fix for Tail::inUnion<U>?

Use:

typedef typename Tail::template inUnion<U> dummy;

Or in modern C++:

using dummy = typename Tail::template inUnion<U>;

Does template mean the result is a type?

No. It only says the named member is a template. The result might be a type or a function call depending on context.

Why does some compiler code seem to work without these keywords?

Some compilers historically accepted missing keywords as extensions or had incomplete two-phase lookup behavior. Standard C++ requires the correct form.

Is typename used for all type names in templates?

No. It is specifically for dependent qualified names where the compiler cannot otherwise know the name is a type.

Take Quiz

Mini Project

Description

Build a small type-traits-style utility that checks whether a container-like type provides a nested value_type and a nested member template rebind<U>. This project demonstrates both forms of disambiguation: using typename for dependent nested types and template for dependent member templates.

Goal

Create a C++ program that successfully accesses a dependent nested type and a dependent member template using the correct syntax.

Requirements

  • Define a type with a nested value_type alias.
  • Define a member template rebind<U> inside that type.
  • Write a generic function or alias that accesses value_type through a template parameter.
  • Write another generic alias that accesses rebind<int> through a template parameter.
  • Compile and print a small result to prove the types were resolved correctly.
Take Quiz

Keep learning

Related questions

View more