https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94960
--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> --- C++17 and below said, Except for inline functions and variables, declarations with types deduced from their initializer or return value (10.1.7.4), const variables of literal types, variables of reference types, and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer. [ Note: The intent is that an inline function that is the subject of an explicit instantiation declaration will still be implicitly instantiated when odr-used (6.2) so that the body can be considered for inlining, but that no out-of-line copy of the inline function would be generated in the translation unit. — end note ] This wording was changed in C++20 by P1815, a modules paper, but I believe the replacement wording still says that the a function is not implicitly instantiated after an explicit instantiation declaration unless it is inline or has a deduced return type. And if it isn't instantiated, it can't be inlined. So if you want an *explicit instantiation declaration* to still be considered for inlining, you need to declare it inline. Most templates don't need to be declared inline, only those that have implicit instantiations suppressed by 'extern template'. So, I think the string case specifically is a library isssue.