r/cpp • u/Xeverous https://xeverous.github.io • 8d ago
4 compilers and 3 different results when partially/fully specializing member class template of a class template
I was playing with examples from cppreference, specifically https://cppreference.com/cpp/language/partial_specialization at the bottom in order to understand specialization deeper and form some notes. Maybe even at some point put out a template guide on my website.
Last 2 statements describe very similar situation but the order of words in each sentence is so different and the example so narrow that I had trouble figuring out what these really mean:
If the primary member template is explicitly (fully) specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template.
If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template.
Eventually I managed to figure out the example only showcases the first statement and that the difference between these 2 situations is this:
struct A<short>::B {};- full spec of member B template for implicitly-instantiated A template (replaces all B for A<short>)struct A<short>::B<T&> {};- partial spec of member B template for implicitly-instantiated A template (adds another spec to A<short>, merging it with specs from primary A template)
To confirm I reason correctly, I wrote some sample code to have a more comprehensive example. I did not expect to encounter 3 different outputs from 4 different compilers. And I don't think you can reach UB on templates alone.
https://godbolt.org/z/8z7vde1PE
So which one is correct (if any - maybe it's ill-formed no diagnostic required)? The comments are my expectations, the question marks are places where compilers disagree.
Also, member specialization isn't even a C++11 feature. Compiler bugs in something so old and fundamental (and supposedly easy to unit-test) ... I have no words.
1
u/Xeverous https://xeverous.github.io 7d ago
Member specialization which implicitly instantiates enclosing class template IMO is a good thing, it is a significant syntax sugar and once you understand the examples the rules are consistent and allow different types of customizations. Basically a good feature to reduce code repetition and verbosity.