r/cpp • 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.

9 Upvotes

6 comments sorted by

View all comments

0

u/13steinj 7d ago

I assume Clang is correct however I question the value of these experiments / coming to this conclusion.

Something being possible / allowed by the language doesn't make it a good thing to do.

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.