views:

252

answers:

5

Is it possible to typedef long types that use templates? For example:

template <typename myfloat_t>
class LongClassName
{
    // ...
};

template <typename myfloat_t>
typedef std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > LongCollection;

LongCollection<float> m_foo;

This doesn't work, but is there a way to achieve a similar effect? I just want to avoid having to type and read a type definition that covers almost the full width of my editor window.

+13  A: 

No, that isn't possible currently. It will be made possible in C++0X AFAIK.

The best I can think of is

template<typename T> struct LongCollection {
    typedef std::vector< boost::shared_ptr< LongClassName<T> > > type;
};

LongCollection<float>::type m_foo;
Leon Timmermans
That works...but you will have to duplicate all your ctors.
James Curran
duplicate all your ctors?
dalle
Indeed, duplicate all your ctors??
mch
By the way, duplicate all your ctors???
Nicola Bonelli
That was my question too!
Leon Timmermans
No, actually you don't. This idiom is called a 'template metafunction' where the nested ::type is the actual type that's created. This means you don't really construct an instance of LongCollection<...> but rather reach in to get the correct type from LongCollection<...>::type.
Dean Michael
+3  A: 

If you don't want to go the macro way you have to make individual typedefs for each type:

typedef std::vector< boost::shared_ptr< LongClassName<float> > > FloatCollection;
typedef std::vector< boost::shared_ptr< LongClassName<double> > > DoubleCollection;
divideandconquer.se
This is, after all, how std::string is a typedef of std::basic_string.
Max Lybbert
+2  A: 

No, but you can get close using a 'helper' type, see this example.

Rob Walker
+1  A: 

Its not exactly what you're asking for, but this might achieve the desired effect depending on your actual situation:

template <typename myfloat_t>
class LongClassName
{
    // ...
};

template <typename myfloat_t>
class LongCollection : public std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > 
{
};

You may need to add some constructors or operators depending on your needs.

John Dibling
Isn't deriving from STL collections considered bad? They do not have virtual functions. I think it would be safer to implement LongCollection in terms of a std::vector by using is as a member variable. Private inheritance may also be an option.
mch
It's not considered good practice but it doesn't actually pose the problems you mention as long as you don't intend for polymorphic usage.
Konrad Rudolph
+2  A: 

The solution shown by Leon is canonical. Bit of background knowledge: This is called a “(template) metafunction” because it is basically a “function” that gets evaluated at compile time. Instead of values, it deals with types: There's a list of input types (the type arguments) and there's a “return value”: The typedef that declares the type name “type”.

“Invocation” works analogously to normal function invocation, albeit with a different syntax:

// Normal function
result = f(args);

// Metafunction
typedef f<args>::type result;

This code construct is an often-used idiom in libraries such as the Boost libraries and even in the STL at one place: allocator_type::rebind<U>::other accomplishes the same thing with the only difference that the typedef type is called other.

Konrad Rudolph
I think you mean 'temlate metafunction'. :)
Dean Michael
Yea, plus the “p”. ;-) Thanks.
Konrad Rudolph