Лично я нахожу, что typedefs очень полезны при работе с шаблонным кодом, как при написании шаблонов, так и при их создании.
Написание шаблонов:
typedefs необходимы для метапрограммирования шаблона. Например, удаление const:
template<typename T>
struct RemoveConst
{
typedef T Type;
};
template<>
struct RemoveConst<const T>
{
typedef T Type;
};
Теперь мы можем получить доступ к константному типу из любого T, создав экземпляр RemoveConst :: Type
Создание шаблонов:
Как и многие вещи в программировании, правильный инструмент для правильной работы.
typedefs, такие как ваш пример
typedef std::list<Foobar> FoobarList;
...
FoobarList GetFoobars();
Звучит вполне разумно, главным образом потому, что имя typedefed носит описательный характер (FoobarList - это список Foobars). Это очень полезно, особенно при работе с контейнерами STL или любыми другими типами шаблонов, которые используют один и тот же интерфейс. представьте следующее объявление класса:
class SomeClass
{
...
std::vector<int> mContainer;
};
Этот класс, вероятно, будет перебирать элементы контейнера, что приведет к коду, подобному следующему:
for(std::vector<int>::iterator It = mContainer.begin(); It != mContainer.end(); ++It)
{
}
Теперь представьте, что после написания вышеуказанного цикла for в 5 различных методах вы понимаете, что вы постоянно вставляете в середину массива, и что std :: list будет гораздо лучше подходить для этой работы.
В этом случае вам нужно будет пройти каждый экземпляр std :: vector :: iterator и изменить объявление.
Вместо этого, что вы можете сделать, это typedef контейнера, который вы используете внутри класса:
class SomeClass
{
typedef std::vector<int> IntContainer;
...
IntContainer mContainer;
};
Это может позволить вам написать очень общий код, который можно очень легко изменить.
for(IntContainer::iterator It = mContainer.begin(); It != mContainer.end(); ++It)
{
}
В этом случае вам нужно всего лишь изменить typedef для IntContainer, и любой экземпляр, который ссылается на него, автоматически изменяется.