Skip to content

Trivia impact: rare

The Static That Splits by Type

one local static, two counters

template <class T>
int next() {
  static int value = 0;
  return ++value;
}

std::cout << next<int>() << ' ' << next<double>() << ' ' << next<int>() << '\n';

How many counters does this function have?

Answer
1 1 2

The int and double calls use different statics; returning to int finds its first counter again.

Why

Each function-template specialization is its own function after instantiation ([temp.inst]). The block-scope static in each such function has static storage duration, but it is not shared with another specialization's block-scope static. Thus next<int> owns one value and next<double> owns another, even though the source declares only one spelling of the variable.

Where it shows up

This is useful for intentionally per-type caches, IDs, and counters. It can be surprising when a template helper was expected to keep one process-wide total instead.

Takeaway: A function-local static in a function template is normally per specialization.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry