5

Possible Duplicate:
C++ template typedef

I am trying to derive a template type of another template by pre-specializing of another template:

template<unsigned a, unsigned b, unsigned c>
struct test
{
    enum
    {
        TEST_X = a,
        TEST_Y = b,
        TEST_Z = c,
    };
};

template<unsigned c>
typedef test<0, 1, c> test01;

However, on GCC 4.4.5, I am getting this error: error: template declaration of ‘typedef’ on the second type (test01).

Guidance would be highly appreciated, as I don't understand what is wrong with my code.

Community
  • 1
  • 1
LiraNuna
  • 57,153
  • 14
  • 112
  • 136
  • 1
    I know this is a duplicate, but I can't find it. EDIT: Aha, [here](http://stackoverflow.com/questions/2795023/c-template-typedef). – GManNickG Feb 15 '11 at 08:23
  • Please use the search next time – the_drow Feb 15 '11 at 08:29
  • 1
    When you look at the duplicate, note that in that particular case the user did not want to use inheritance, even if that was a common pattern for C++98 compilers: `template struct test01 : test<0,1,c> {}` There is a slight difference, as you are adding inheritance to the mix and that has some pitfalls (beware: do not delete the type through pointers to `test<0,1,N>` as that will cause UB, always destroy at the `test01` level) – David Rodríguez - dribeas Feb 15 '11 at 08:59

2 Answers2

10

This syntax isn't allowed by C++03. The nearest work-around is:

template<unsigned c>
struct test01
{
    typedef test<0, 1, c> type;
};

typedef test01<2>::type my_type;

In C++0x, we can do this:

template<unsigned c>
using test01 = test<0, 1, c>;
GManNickG
  • 459,504
  • 50
  • 465
  • 534
2

Just for the sake of listing an alternative:

template <typename C>
struct test01 : test<0, 1, C> { };

test01<4> my_test014;

This does create new, distinct types and not simply aliases for instantiations of the base template :-(.

Tony Delroy
  • 94,554
  • 11
  • 158
  • 229
  • 1
    Sadly it doesn't guard against: `test<0, 1, 2>* x = new test01<2>(); delete x; // oops, UB!`. – GManNickG Feb 15 '11 at 08:53
  • @GMan: obviously true if you don't bother to put a `virtual` destructor in `test<>` (same old issue as derivation from Standard containers, and practically irrelevant in my experience and coding style, but everyone lives by the concerns that seem significant to them...) – Tony Delroy Feb 15 '11 at 09:24
  • Since I am doing mostly template meta-programming, this is fine by me. However, I do understand the difference. – LiraNuna Feb 15 '11 at 09:27
  • Does not work for #include template struct MyShared : public std::shared_ptr{}; – Cobaia Jun 30 '14 at 13:50
  • @Cobala: it I was inclined to put as much effort and detail into this comment as you did for yours, I'd just say "you're wrong", but to be more constructive ;-P... here's [an ideone example](http://ideone.com/7yN8hO) proving it "works", but more seriously you probably want to add a convenience function or two - e.g. at least constructor forwarding ala `using std::shared_ptr::shared_ptr;` inside `MyShared`. Cheers. – Tony Delroy Jun 30 '14 at 16:37