5

I'm trying to specialize a template class inside another class but the compiler won't let me. The code works outside of class Foo but not inside and I want struct Bla to be private to class Foo.

class Foo {
   template<typename ... Ts> struct Bla; 
   template<> struct Bla<> { static constexpr int x = 1; };
};

error: explicit specialization in non-namespace scope 'class Foo'
Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42

2 Answers2

4

You simply cannot do that. The error sums it up nicely. Class templates can only be specialized in namespace scope. class Foo is not a namespace.

You can do it external to the class, as per this example from the standard [temp.class.spec]:

A class template partial specialization may be declared or redeclared in any namespace scope in which its definition may be defined (14.5.1 and 14.5.2). [ Example:

 template<class T> struct A {  
     struct C {
         template<class T2> struct B { };
     };
 };

 // partial specialization of A<T>::C::B<T2>
 template<class T> template<class T2>
   struct A<T>::C::B<T2*> { };

A<short>::C::B<int*> absip; // uses partial specialization

—end example ]

Barry
  • 286,269
  • 29
  • 621
  • 977
3

You cannot specialize inside the class, use:

class Foo {
public: // so we can test it easily
   template<typename ... Ts> struct Bla; 
};

// specialize it outside the class
template<> class Foo::Bla<> { static constexpr int x = 1; }; 

int main()
{
    std::cout << Foo::Bla<>::x;
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Thanks, that's exactly the solution. – Goswin von Brederlow Apr 09 '15 at 23:36
  • @GoswinvonBrederlow note that I used `public` here, so I can display `Bla::x`. However I guess you are using a `friend` or displaying via a member function, in which case you should be ok. – vsoftco Apr 09 '15 at 23:39
  • This makes me think though. Doesn't that allow violating the privacy of a class? `class Foo { static constexpr int y = 1; public: template struct Bla; }; template<> struct Foo::Bla<> { static constexpr int x = y; };` Foo::y is private but by specializing Bla any user of Foo can gain access to it through Bla::x. – Goswin von Brederlow Apr 09 '15 at 23:40
  • @GoswinvonBrederlow my answer is too long to post here. check this out http://stackoverflow.com/q/424104/3093378 and search for "backdoor" – vsoftco Apr 09 '15 at 23:41
  • @GoswinvonBrederlow and that's probably exactly what you meant: http://ideone.com/dBV0eU – vsoftco Apr 10 '15 at 00:00