3

I have a class like this:

template <class T>
class Foo;

I want to have a specialization of

template <>
class Foo < size_t N >;

but that doesn't compiles for me:

my main is like:

Foo<int> p;  // OK
Foo<15> p2;  // fails to compile

What am I missing?

Negative Zero
  • 1,224
  • 3
  • 10
  • 19
  • Your second `Foo` is not a specialization, it is an entirely different template (it does not take the same kind of parameter). Unlike functions, templates cannot be overloaded (I don't know if there is a good reason for this limitation, though. If anyone has an explanation, I'll be happy to hear it.). – Luc Touraille Aug 15 '12 at 11:50

3 Answers3

5

You can't - your template takes one type parameter, always. Specializations can only be more special than that, but not different (hence the name).

Maybe you can use an auxiliary template to store value information:

template <typename T, T Val> struct ValueWrapper { };

template <typename T> struct Foo;

templaet <typename T, T Val> struct Foo<ValueWrapper<T, Val>>
{
    typedef T type;
    static type const value = Val;

    // ...
};

Usage:

Foo<char> x;
Foo<ValueWrapper<int, 15>> y;
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
3

There are three kinds of template parameters: Those that represent a type (e.g. class T or typename T), those that represent a non-type (e.g. int N or size_t N), and those that represent a template (e.g. template <class T2> class T).

The parameter defined for your template is of the first kind (a type parameter), but the specialization assumes the second kind (a non-type parameter). That doesn't work. The parameters of the specialization must be of the same kind as the corresponding parameters of the primary template definition.

jogojapan
  • 68,383
  • 11
  • 101
  • 131
  • 1
    To put it in perspective, here's a sample, with redundant template arguments: http://ideone.com/fxKM6 – chris Aug 15 '12 at 04:31
  • 2
    @jogojapan: "three kinds of templates" - it's more a case of kinds of template parameters... any given template can mix and match parameters of those "kinds". – Tony Delroy Aug 15 '12 at 04:36
  • @TonyDelroy True. My answer implicitly assumed there is only one template parameter, because that was the case in the OP's example. I have reworded it. Thanks. – jogojapan Aug 15 '12 at 04:41
2

You can specialize the class using an intermediate class:

template <class T>
class Foo
{
public:
  static const bool is_number = false;
};
template <size_t number>
struct ic
{};
template <size_t N>
class Foo < class ic<N> >
{
public:
   static const bool is_number = true;
   size_t getN() const
   {
      return N;
   } 
};

int main()
{
   Foo<int> p;  
   Foo<ic<15> > p2;  
   cout << "p.is_number = " << p.is_number << endl;
   cout << "p2.is_number = " << p2.is_number  << endl;
   cout << "p2.getN() = " << p2.getN() << endl;
   return 0;
}
SergV
  • 1,269
  • 8
  • 20