1

I am aware of the fact it is not possible to specialize an alias template.

The fact is that I often find the following recurring pattern:

template<class Code, Code code>
struct BaseStruct;

enum MyCode {A,B,C};

template<MyCode code>
using MyStruct = BaseStruct<MyCode, code>;

template<> // Error not possible
struct MyStruct<MyCode::A>
  {
  };


template<> // Ok but too long to write
struct BaseStruct<MyCode, MyCode::A>
  {
  };

Sometimes I have to write many specializations and BaseStruct can have other template parameters or with maybe have a long name, so the ideal would be to use an alias and then specialize it.

What do you guys do in this situation? I'd rather not using macros or other ways that introduce overhead.

PS I'm using c++11

max66
  • 65,235
  • 10
  • 71
  • 111
svoltron
  • 365
  • 1
  • 10

2 Answers2

2

[Too long for a comment]

Depending on your use-case, inheritance instead of an alias template might work, but it's hard to say from your toy example.

template<class Code, Code code>
struct BaseStruct;

enum MyCode {A,B,C};

template<MyCode code>
struct MyStruct : BaseStruct<MyCode, code> {};

template<> struct MyStruct<MyCode::A> {};
template<> struct MyStruct<MyCode::B> {};
template<> struct MyStruct<MyCode::C> {};
Henri Menke
  • 10,705
  • 1
  • 24
  • 42
  • This is a good alternative and for most of the cases it should work. I was looking for a generic method that does not have overhead. As far as I recall the Empty base optimization is not guaranteed. What if I want to use this structure with attribute(packed) ? – svoltron Oct 24 '18 at 10:22
1

I know that C-style macros ar distilled evil but... if the problem is that is "too long to write", before C++17 the best I can imagine is define a macro as follows

#define BSMacro(X) \
   template <>    \
   struct BaseStruct<MyCode, MyCode::X >

The following is a full working C++11 example

template<class Code, Code code>
struct BaseStruct;

enum MyCode {A,B,C};

template<MyCode code>
using MyStruct = BaseStruct<MyCode, code>;

#define BSMacro(X) \
   template <>    \
   struct BaseStruct<MyCode, MyCode::X >

BSMacro(A)
 { };

BSMacro(B)
 { };

BSMacro(C)
 { };

int main ()
 {
   MyStruct<A>  bsa;
   MyStruct<B>  bsb;
   MyStruct<C>  bsc;
 }

Obviously, starting from C++17, you could use auto (as pointed by Jarod42)

template <auto code>
struct BaseStruct 
max66
  • 65,235
  • 10
  • 71
  • 111
  • Thank you for the feedback. A solution is for sure this, but as I wrote in the question I'd prefer to avoid macros for other reasons. I was also thinking to some kind of proxy class but that would introduce overhead :/ – svoltron Oct 24 '18 at 09:45
  • 1
    @svoltron - I'm also interested in no-macro solutions (I hate macros) but is the best I can imagine. – max66 Oct 24 '18 at 09:47