Maximal Munch Rule and Nested Templates in C++

This article provides an overview of the maximal munch rule in compiler design, its historical impact on nested template declarations in C++, and how modern C++ standards resolved the issue. Readers will learn the definition of the maximal munch principle, understand why the sequence >> caused compilation errors in earlier versions of the language, and see how the compiler specification was adapted to eliminate the need for manual spacing between closing template brackets.

What is the Maximal Munch Rule?

The maximal munch rule (also known as the longest match rule) is a fundamental principle of lexical analysis in programming language compilers. During the tokenization phase, the lexer scans the source code from left to right and gathers characters to form tokens. According to the maximal munch rule, whenever there is ambiguity regarding where one token ends and another begins, the lexer must choose the longest valid sequence of characters that forms a token.

For example, given the expression a+++b, the lexer evaluates + characters greedily. Because ++ is a valid two-character token and is longer than the single-character token +, the expression is tokenized as a, ++, +, b rather than a, +, ++, b.

The Nested Template Problem Pre-C++11

In C++98 and C++03, the maximal munch rule created a well-known issue with nested template instantiations, such as:

std::vector<std::list<int>> nestedList;

Because the lexer operates before the parser understands the semantic context of template brackets, it applies the maximal munch rule strictly. When encountering the two adjacent greater-than symbols >>, the lexer combines them into a single right-shift operator token (>>) instead of two separate closing angle bracket tokens (> followed by >).

Consequently, the parser received a right-shift operator where it expected two closing template delimiters, causing a syntax error:

error: '>>' should be '> >' within a nested template argument list

To work around this limitation, developers were required to manually insert whitespace between closing brackets:

std::vector<std::list<int> > nestedList; // Valid in C++98/03

How Modern C++ Resolves >> in Templates

Starting with C++11, the C++ standard introduced a specific exception to the maximal munch rule to improve developer ergonomics. Rather than treating tokenization as entirely independent of grammar, the standard introduced a context-sensitive rule for template syntax.

Under the updated specification, when the compiler is inside the context of a template argument list:

  1. A > character that would normally be treated as the first character of a multi-character token (such as >>, >>=, or >=) is treated as a standalone closing angle bracket token if it terminates a template argument list.
  2. If >> appears, the lexer/parser splits the symbol into two distinct > tokens, each capable of closing an open template declaration.

As a result, modern C++ compilers allow consecutive closing brackets without whitespace:

std::map<int, std::vector<std::string>> dictionary; // Fully valid in C++11 and later

This resolution maintains backward compatibility with the bitwise right-shift operator in arithmetic expressions while contextualizing token boundaries within template declarations.