> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Template Template Parameter

A template template parameter is a template parameter that acts as a placeholder expecting an uninstantiated class template or alias template as its argument. It allows a host template to receive a template rather than a fully instantiated type, granting the host template the authority to instantiate the provided template internally using types, non-type parameters, or other templates of its own choosing.

## Syntax

The declaration of a template template parameter requires its own nested template parameter list. This nested list defines the exact signature (arity and parameter kinds) of the templates that can be passed as arguments.

```cpp theme={"dark"}
// 'TemplateParam' is a template template parameter expecting a template with exactly one type parameter.
template <template <typename U> class TemplateParam>
class HostTemplate {
    // Instantiating the template parameter internally
    TemplateParam<int> int_instance;
    TemplateParam<double> double_instance;
};
```

*Note: Prior to C++17, the keyword `class` was strictly required to declare a template template parameter. Since C++17, `typename` is also permitted and functionally identical in this context:*

```cpp theme={"dark"}
// C++17 syntax
template <template <typename U> typename TemplateParam>
class HostTemplate;
```

## Parameter Matching Rules

When passing a template argument to a template template parameter, the compiler enforces matching rules between the nested parameter list and the provided template.

**Pre-C++17 (Strict Matching):**
The parameter list of the argument template must exactly match the parameter list of the template template parameter. Default template arguments in the argument template are ignored during this evaluation.

```cpp theme={"dark"}
#include <memory>

template <template <typename> class T> 
struct Host {};

template <typename U, typename Alloc = std::allocator<U>> 
struct Container {};

// ERROR in C++14: Container has two parameters (even though one has a default), 
// but Host expects a template with exactly one parameter.
Host<Container> h1; 
```

**C++17 and Later (Relaxed Matching):**
The matching rules were relaxed (P0522R0). A template argument `A` is considered a valid match for a template template parameter `P` if `P` is at least as specialized as `A`. Because the parameter `template <typename> class` is more specialized than the argument `template <typename, typename> class`, and the extra parameters in the argument have default values, the match succeeds.

```cpp theme={"dark"}
// VALID in C++17: The compiler recognizes that Container can be 
// instantiated with a single type argument due to the default allocator.
Host<Container> h2; 
```

## Variadic Template Template Parameters

Template template parameters can be variadic. A variadic template template parameter specifically expects a variadic template as its argument (a template that takes zero or more parameters). It will strictly reject fixed-arity templates, even if the fixed arity falls within the "zero or more" conceptual range.

```cpp theme={"dark"}
// Accepts only variadic templates
template <template <typename...> class VariadicTemplateParam>
class HostTemplate {
    VariadicTemplateParam<int> single_arg;
    VariadicTemplateParam<int, float, char> multi_arg;
};

template <typename... Types> struct VariadicContainer {};
template <typename T> struct SingleContainer {};

HostTemplate<VariadicContainer> valid_host; // OK
// HostTemplate<SingleContainer> invalid_host; // ERROR: SingleContainer is not variadic
```

## Mixing Parameter Kinds

The nested parameter list of a template template parameter can include type parameters, non-type template parameters (NTTPs), and even other template template parameters, dictating a highly specific signature.

```cpp theme={"dark"}
#include <cstddef>

// Expects a template that takes a type and a non-type parameter of type std::size_t
template <template <typename T, std::size_t N> class ArrayLike>
class HostTemplate {
    ArrayLike<int, 10> buffer;
};
```

## Restrictions

1. **Class and Alias Templates Only:** Only class templates and alias templates can be passed as arguments to a template template parameter. Function templates and variable templates are strictly prohibited.
2. **Nested Parameter Names:** The names of the parameters within the nested template parameter list (e.g., `U` in `template <typename U> class`) cannot be referenced within the body of the host template. While they are often omitted for simple type parameters, they are strictly required if a subsequent parameter in the nested list depends on a previous one.

```cpp theme={"dark"}
// 'T' is strictly required here because the non-type parameter 'Value' depends on it.
template <template <typename T, T Value> class DependentParam>
class HostTemplate;
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C++ Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
