73

C++ 0x has template aliases (sometimes referred to as template typedefs). See here. Current spec of C++ does not.

What do you like to use as work around ? Container objects or Macros ? Do you feel its worth it ?

Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
George Godik
  • 1,716
  • 1
  • 14
  • 19

3 Answers3

106

What do you like to use as work around ? Container objects or Macros ? Do you feel its worth it ?

The canonical way is to use a metafunction like thus:

template <typename T>
struct my_string_map {
    typedef std::map<std::string, T> type;
};

// Invoke:

my_string_map<int>::type my_str_int_map;

This is also used in the STL (allocator::rebind<U>) and in many libraries including Boost. We use it extensively in a bioinformatical library.

It's bloated, but it's the best alternative 99% of the time. Using macros here is not worth the many downsides.

(EDIT: I've amended the code to reflect Boost/STL conventions as pointed out by Daniel in his comment.)

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 3
    If you use 'type' instead of 'Type' (or in addition to) this will work better with Boost.MPL. Which can be useful, so I think it's a good convention to encourage. – Daniel James Sep 16 '08 at 11:44
  • 5
    @Zenikoder: It’s perfectly reasonable to call it a metafunction, and most C++ metaprogramming experts do so (e.g. the Boost people). There doesn’t exist one rigorous definition but personally I call everything a metafunction that, at compile-time, yields a type or compile-time constant given some input. That is, any mapping from an input to an output at compile time. I don’t know that any more reasonable or more widely accepted definition exists. Finally, can I ask why you object to this usage of the term? – Konrad Rudolph Jan 24 '11 at 12:05
  • 4
    @matthieu it is a metafunction because it computes a type at compile time – Ghita May 20 '12 at 06:56
  • could you please add an explanation of how to have a function return this type please? – max Aug 19 '14 at 00:40
  • @MoKi I don’t understand what you mean. – Konrad Rudolph Sep 02 '14 at 11:54
12
template <typename T>
struct my_string_map : public std::map<std::string,T> 
{
};

You shouldn't inherit from classes that do not have a virtual destructor. It's related to destructors in derived classes not being called when they should be and you could end up with unallocated memory.

That being said you could *****probably***** get away with it in the instance above because you're not adding any more data to your derived type. Note that this is not an endorsement. I still advice you don't do it. The fact that you can do it doesn't mean you should.

EDIT: Yes, this is a reply to ShaChris23's post. I probably missed something because it showed up above his/her message instead of below.

xghost
  • 121
  • 1
  • 3
  • 3
    is this meant as a reply to ShaChris23's post? – Evan Teran Jan 18 '10 at 23:06
  • These aren't forums, post do not appear in chronological order. Normally, this would be a comment. You cannot, so perhaps a community wiki answer would have done. Either way, the question is quite old. – GManNickG Jan 18 '10 at 23:25
  • 4
    I noticed that it's quite old, but I thought it was a good thing to make sure it was not encouraging incorrect practices. ttyl – xghost Jan 18 '10 at 23:36
0

Sometimes you can just explicitly write out the untemplated typedefs for all the necessary types. If the base class is templated on multiple template args with only one type desired to be typedefed you can inherit a specialized class with typedef effectively included in the inherited class name. This approach is less abstruse than the metafunction approach.

Andrei Pokrovsky
  • 3,590
  • 3
  • 26
  • 17