I'm doing some self-study concerning statistics right now and while doing so I want to get some practice with templated classes. As a result, I'm working on a collection of templated classes designed for statistical analysis. What I would like to know is how I would handle creating typedefs for these template classes, if it's even possible. I have created this basic class structure (data and function members omitted for clarity):

namespace Statistics {
  template <typename T> class Stats {
  };

  template <typename T> class CategoricalStats : public Stats {
  };

  template <typename T> class NumericalStats : public Stats {
  };

  //typedefs for derived classes, see below

} //end Statistics namespace

The problem that I am having is "Categorical" Stats can also be called "Qualitative" Stats and "Numerical" Stats can also be called "Quantitative" Stats. I would like to define typedefs for each of them to accommodate the alternate names, but my compiler won't accept anything I've tried. In other words, I would like to be able to say either NumericalStats<int> OR QuantitativeStats<int> and have them mean the same thing. What do I need to do, if it's even possible? What I have tried:
1.)

typedef CategoricalStats<T> QualitativeStats<T>;
typedef NumericalStats<T> QuantitativeStats<T>;

Error(s):

error C2065: 'T' : undeclared identifier
error C2143: syntax error : missing ';' before '<'

2.)

template <typename T> typedef CategoricalStats<T> QualitativeStats<T>;
template <typename T> typedef NumericalStats<T> QuantitativeStats<T>;

Error(s):

a typedef template is illegal
syntax error : missing ';' before '<'
unrecognizable template declaration/definition
syntax error : '<'
'T' : undeclared identifier

3.)

template <typename T> typedef CategoricalStats QualitativeStats;
template <typename T> typedef NumericalStats QuantitativeStats;

Error(s):

a typedef template is illegal
'Statistics::CategoricalStats Statistics::QualitativeStats' : cannot be a template definition

I have seen 2 versions of the errors that say "a typedef template is illegal" so I'm guessing it can't be done. I know that something like typedef NumericalStats<int> NSint; is okay, but that doesn't do what I want.

Any other suggestions, comments? Thanks.

Edited 6 Years Ago by Fbody: n/a

I have tried this as well:

typedef CategoricalStats QualitativeStats;
typedef NumericalStats QuantitativeStats;

it produces:

'Statistics::CategoricalStats' : use of class template requires template argument list
see declaration of 'Statistics::CategoricalStats'

I just realized I didn't mention it.

Edited 6 Years Ago by Fbody: n/a

Its not possible to do what you are doing. The best you can get is :

template<typename T> class CategoricalStats { ... }
template<typename T> struct QualitativeStats{
 typedef CategoricalStats<T> Type;
}
//...
QualitativeStats<float>::Type qstats;

You have that ugly extra level of indirection, but it gets the job done. See here for more details.

I was afraid I would have to do something like that. :(

For the sake of simplicity, I don't think I'm going to worry about that functionality.

Thanks.

Edited 6 Years Ago by Fbody: n/a

I'm not sure if I'm understanding the problem fully, but it looks like you are trying to give the same template two names?

You could try making a second template with the second name you want, and add

friend class QuantitativeStats<T>;

That should allow you to create a QuantitativeStats class that uses all the required variables.

I also found a similar problem where someone suggested wrapping the typedef in a structure.

template <typename T> struct QuantitaveStats
{
    typedef NumericalStats<T> type;
}

Then invoked by

QuantitativeStats<t>::type myStat;

Anyways, I'll admit this is outside my knowledge, but thought I'd fish around for an answer.

Edit: firstPerson beat me to it. Guess I surfed around to long :)

Edited 6 Years Ago by kes166: n/a

There is always this :

struct A{
  void methodA(){...};
};
class B{
 A a;
 void methodA(){ a.methodA(); }
}

But thats retarded.

There is always this :

struct A{
  void methodA(){...};
};
class B{
 A a;
 void methodA(){ a.methodA(); }
}

But thats retarded.

Hmmm.... I don't know if I'd call it "retarded", unusual perhaps. Then again, it seems the whole situation is a bit unusual...

Class B is really just a wrapper class, which isn't unusual for certain situations.

:icon_idea:
I wonder if I could do it with inheritance... I know it's not a typical use of inheritance (it's not actually a "specialization"), but there is already an inheritance structure in place. Plus, for example, it would make all members of Numerical members of Quantitative without as many maintenance headaches. I'm not sure what it would do for the performance though...

This is OOP, so what happens under the hood isn't really supposed to matter to the end user any way. It would still be possible to have a declaration such as Stats *myStats = new Quantitative; it just happens to pass through Numerical on the way up to Stats...

Edited 6 Years Ago by Fbody: n/a

This question has already been answered. Start a new discussion instead.