Remix.run Logo
Why export templates would be useful in C++ (2010)(warp.povusers.org)
12 points by PaulHoule 11 days ago | 1 comments
jcranmer 43 minutes ago | parent [-]

It's worth pointing out that export templates were removed from C++ based on feedback from the most expert implementers of C++ on implementing the feature, which unanimously resolved to "don't": https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n14....

It's also worth noting that the main claim of this article as to its advantage is in fact listed as "phantom advantage #1" in the paper arguing for its removal. The paper doesn't do a good job of explaining this for lay people, but the basic problem is that export templates actually end up working entirely backwards from the way you think they work--rather than letting you hide the implementation details from other compilation units, they actually force you to expose all of the implementation details, even implementation details not normally fronted to the user, in ways that cause the common slight differences to snowball into catastrophic errors.

The feature people want is to not put the template body in a header. But the problem with C++ templates is that template bodies are instantiated at their first point of use. As the post notes, extern templates let you have a dedicated translation unit provide the instantiations with usefully hidden definition, so long as you manually list all of the instantiations that you might need. And this is possible in modern C++, and is used in some cases where the universe of possible templated values is relatively small and self-contained (say, string libraries or numeric libraries).

Export templates theoretically allow you to delegate the expansion of a template without manually listing all of the possible expansions. But the compilation unit that contains the body doesn't know--it can't know--all of the possible expansions. So the compilation unit that uses the exported template, the only one that knows the expansions it needs, has to generate the expansion. From the body contained in the other compilation unit. Which means the first compilation unit needs to export all of the details necessary to recreate the body for an arbitrary template instantiation. And, were the feature to have lasted long enough for multiple versions of C++ to come into play, a current C++ compiler would have to figure out how to instantiate a template which is half C++26 and half C++98, and I don't mean "C++98 source code compiled with C++26", I mean "code compiled in C++98 mode with C++98 semantics."

At the end of the day, it turns out to be easier to literally include the entire source code of the template as an included header file than it is to do all of the magic required to make export templates work.