Hello,

Would you please give a hint to define a template class specialization in a template class which is in a namespace

I have tried following code with gcc 4.1 and get an error message but Visual studio has no problem with it.

namespace A {
   template <typename T>
   struct B {
   template <typename X>
   struct G;
   template <>
   struct G<int>;
};
}

Thanks in advance.

Recommended Answers

All 2 Replies

You've stumbled on a gray area, but the long and short of things is that what you're trying to do is illegal in standard C++, and all of the direct workarounds are also illegal. An explicit specialization needs to be in the enclosing namespace scope, which would place it outside your class:

namespace A {
  template <typename T>
  struct B {
    template <typename X>
    struct G;
  };

  template <typename T>
  template<>
  struct B<T>::G<int>;
}

The problem is that this is also illegal because you aren't allowed to specialize the nested class without also specializing the containing class. This compiles, but limits you severely:

namespace A {
  template <typename T>
  struct B {
    template <typename X>
    struct G;
  };

  template<>
  template<>
  struct B<int>::G<int>;
}

If B weren't a template class, this wouldn't be a problem. The end result is that you're stuck with indirect fixes like wrapping the whole of B and its "nested" classes in a nested namespace:

namespace A {
  namespace B {
    template <typename T>
    struct B {
    };

    template <typename X>
    struct G;

    template<>
    struct G<int>;
  }
}

Now the problem goes away because you're not trying to nest a specialized class inside a template class, and you still have the benefit of a unique scope for B, G, and all of G's specializations.

you can get the effect that you intended (specializing the nested class without also specializing the containing class) this way: delegate the nested template to another template at some namespace scope which has an explicit specialization:

#include <iostream>

namespace A
{
  namespace impl_detail
  {
    // generalization:
    template < typename T, typename X > struct B_G
    {
      static inline const char* id() { return "generalization" ; }
    } ;

    // specialization:
    template < typename T > struct B_G< T, int >
    {
      static const char* id() { return "specialization (int)" ; }
    } ;
  }

  template <typename T>
  struct B
  {
    template <typename X> struct G : impl_detail::B_G<T,X> {} ;
  };
}

int main()
{
  std::cout << A::B<double>::G<void>::id() << '\n' ;
  std::cout << A::B<void>::G<double>::id() << '\n' ;
  std::cout << A::B<double>::G<int>::id() << '\n' ;
  std::cout << A::B<void>::G<int>::id() << '\n' ;
}

as Narue mentioned, it is a gray area, and has been the subject of debate since 1988.
this issue is still not closed and is part of the C++ Standard Core Language Defect Reports (under consideration by the working group).
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.