Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specialize a template using a member enum?

Tags:

struct Bar {
  enum { Special = 4 };
};

template<class T, int K> struct Foo {};
template<class T> struct Foo<T,T::Special> {};

Usage:

Foo<Bar> aa;

fails to compile using gcc 4.1.2 It complains about the usage of T::Special for partial specilization of Foo. If Special was a class the solution would be to a typename in front of it. Is there something equivalent to it for enums (or integers)?

like image 432
Altan Avatar asked Dec 28 '10 04:12

Altan


People also ask

What is template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

Can you partially specialize a C++ function template?

You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.


2 Answers

Since that is not allowed by C++ as explained by Prasoon, so an alternative solution would be to use EnumToType class template,

struct Bar {
  enum { Special = 4 };
};

template<int e>
struct EnumToType
{
  static const int value = e;
};

template<class T, class K> //note I changed from "int K" to "class K"
struct Foo
{};

template<class T> 
struct Foo<T, EnumToType<(int)T::Special> > 
{
   static const int enumValue = T::Special;
};

Sample code at ideone : http://www.ideone.com/JPvZy


Or, you can simply specialize like this (if it solves your problem),

template<class T> struct Foo<T,Bar::Special> {};

//usage
Foo<Bar, Bar::Special> f;
like image 158
Nawaz Avatar answered Sep 22 '22 21:09

Nawaz


The type of a non-type template argument cannot depend on a template parameter of a partial specialization.

ISO C++03 14.5.4/9 says

A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.

template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; //error
template <int I, int J> struct B {};
template <int I> struct B<I, I> {};     //OK

So something like this is illegal template<class T> struct Foo<T,T::Special> {}; because T::Special depends on T

The usage is also illegal. You have provided one template argument but you need to provide two.

like image 28
Prasoon Saurav Avatar answered Sep 26 '22 21:09

Prasoon Saurav