You can create type aliases using either using (newer C++ syntax) or typedef (older C syntax). The syntax for using seems a little more natural and easier to read. Additionally, using can be used with templates, whereas it's an error to try and create a template with typedef.
Here's an example contrasting the two (using awful pointer-to-member-function syntax):
class ClassName;
/* Fixed class type */
typedef void (ClassName::*MemberFunctionPtr1)();
using MemberFunctionPtr2 = void (ClassName::*)();
/* Templated class type */
template<typename T> typedef void (T::*MemberFunctionPtr3)(); /* Error */
template<typename T> using MemberFunctionPtr4 = void (T::*)();
It does have the limit that it can't be templatized but I don't really see a use case that would really make using any more attractive to me than typedef.
type_traits in C++14 adds templated using aliases, which make using it much less verbose - otherwise you have to specify typename and ::type all over the place, when type_traits is already disgustingly verbose to begin with.
Also, if there's some templated container class or whatever that also takes other template args like an allocator, or initial size, etc., you can make a template using alias that takes the container item type and fills in the other args for you, like:
template <typename T, size_t InitialSize, typename Allocator>
class MySmallVector {
...
std::aligned_storage_t<sizeof(T), alignof(T)> initialBuffer[InitialSize];
};
class BadIdea {
public:
void* Alloc(size_t size) { return alloca(size); }
void Free(const void*) { }
};
template <typename T>
using WhatCouldGoWrong = MySmallVector<std::pair<T, T>, 0xFFFFFFFFFFFFFFFF, BadIdea>;
@lordpalandus: Neither using nor typedef require the pre-processor. I think you're thinking of #define aliases.
@Arklon: I think I missed the point of the example here.
In particular, I don't see what is wrong with BadIdea. I assume that is just a really simple allocator class. From what I see, it's never even going to have a chance to be used. The bad idea is simply the huge initial buffer size set by the WhatCouldGoWrong alias. And also partly the misleading name MySmallVector, since the library user is free to make that huge if they wanted to by setting a large initial size.
Hmm, also just noticed the std::pair. I assume the using clause is creating an alias for a 2D vector.
This is my understanding of the code:
class SimpleAllocator {
public:
void* Alloc(size_t size) { return alloca(size); }
void Free(const void*) { }
};
template <typename T, size_t InitialSize, typename Allocator>
class SmallSizeOptimizedVector {
...
std::aligned_storage_t<sizeof(T), alignof(T)> initialBuffer[InitialSize];
};
template <typename T>
using RidiculouslyHuge2DVector = SmallSizeOptimizedVector<std::pair<T, T>, 0xFFFFFFFFFFFFFFFF, SimpleAllocator>;
RidiculouslyHuge2DVector<float> vector2D; // { {x1, y1}, {x2, y2}, ... }
I'm guessing the example of the usefulness of using was actually the 2D part, since that doubles up on the type. And also the ability to fill in the other details so you don't need to worry about them. Just that wasn't such a good thing in this example because it filled in bad details for one of those fields.