14

Here is the code :

template <typename T>
struct A
   {
   template <typename U>
   struct B;
   };
template <typename T> template <> // 0_o
struct A<T>::B<int> {};

I know I can't do this but I'm more interested to know logically Why can't I specialize the nested template member without specializing enclosing class template first?

I appreciate any help with logical explanation :)

Edit :

Andrei Alexandrescu's reply : "There's no particular reason - it's just a language rule."

Community
  • 1
  • 1
Mr.Anubis
  • 5,132
  • 6
  • 29
  • 44
  • Might be a duplicate of this.. http://stackoverflow.com/questions/568046/nested-template-specialization – Ajai Feb 09 '12 at 21:37
  • 1
    @Ajai How's this duplicate? 0_o, I'm looking for an explanation – Mr.Anubis Feb 09 '12 at 21:39
  • Perhaps it'd be ambiguous if you had to decide between an outer and an inner specialization (e.g. assume both are partially specialized, separately). – Kerrek SB Feb 09 '12 at 21:41
  • 2
    +1 for the interesting question, surprised it hasn't been asked before. :) – John Humphreys Feb 09 '12 at 21:44
  • Had to nuke my answer because the reasoning doesn't make sense anymore after learning that a partial specialization is indeed allowed: http://ideone.com/JfhZr. So it all falls back on why *explicit* specializations aren't allowed... – Xeo Feb 09 '12 at 22:27
  • Btw, for those interested, here's [a closed DR about explicit specializations inside a class](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#727). :( – Xeo Feb 09 '12 at 22:36
  • 1
    See [this SO question](http://stackoverflow.com/questions/2537716/why-is-partial-specialziation-of-a-nested-class-template-allowed-while-complete). – Jesse Good Feb 09 '12 at 22:58

1 Answers1

1

Here's an idea based on Xeo's example: First, let's have our candidate primary template:

template <typename T> struct Foo
{
    template <typename U> struct Bar { /* ... */ };
    /* ... */
};

Now suppose we want to specialize the inner template, hypothetically:

template <typename T> template <> struct Foo<T>::Bar<bool> { /* ... */ }
// not actual C++!

But now suppose there are specializations of Foo:

template <> struct Foo<int>
{
    template <typename U> struct Bar { /* ... */ };
};
template <> struct Foo<char>
{
    template <typename U> U Bar() { }
};

Now what if you want to use Foo<S>::Bar<bool>? When S = char, we cannot use the inner specialization, because it makes no sense. But if we disallow the inner specialization for all specializations of the outer template, then Foo<int>::Bar<bool> isn't specialized, while Foo<float>::Bar<bool> will be specialized. So our hypothetical inner specialization does not apply to Foo<int>, even though one might have expected that it should.

This isn't a real technical reason that it can't be done, but just an illustration how it would have very unexpected behaviour. (For instance, imagine the specialization for int was written later, and existing code depended on the inner specialization.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • See my comment on the question, it seems only explicit specializations aren't allowed, for whatever reason. And it indeed seems like you suggested in your comment to my answer that the specialization only applies to the primary template. – Xeo Feb 09 '12 at 22:31