What's So Hard About Cass Types as Non-type Template Parameters? -- Barry Revzin
Previously, I tried to answer the question: what’s so hard about constexpr
allocation?. Today, we continue what will become a series of posts about attempting to explain the issues behind a bunch of hard problems we’re trying to solve. The next problem: class types as non-type template parameters.
What's So Hard About Cass Types as Non-type Template Parameters?
by Barry Revzin
From the article:
Before C++20, the only types you could use as non-type template parameters were scalar types (like
int
andenum
s, but not floating point), pointers (including pointers-to-members), and references. Notably, not class types.Floating point types were also added in C++20.
The hard question about handling class types is: how do you determine template argument equivalence? Class types can define their own equality. But you don’t really want to rely on that, since now matching specializations becomes a quadratic problem — you can’t really do much when determining the instantiation for some template
f<x>
other than looping through every other valuevi
to see ifx == vi
.The other problem is we need
==
to really be strong enough. One very easy problem to run into in this space is violating the One Definition Rule (ODR). One essential, core requirement for templates is that instantiating the same template with the same arguments has to yield the same code.