namespace A{
int i = 3;
}
namespace B{
int i = 1;
}
void foo(){
A::i = 53;
B::i = 12;
}Мы можем использовать одно и то же имя для переменной i.
Но иногда, это может становиться очень долгой и кропотливой работой каждый раз при обьявлении переменной или функции использовать оператор :: (оператор разрешения области видимости / scope resolution operator) для получения нужного нам типа.На редите я нашел вот такое:
LibBar::GadgetHelpers::SomeGadgimathing foobar(LibBar::GadgetHelpers::SomeGadget<type> gadget,LibBar::GadgetHelpers::GadgimathingOptions options);
Именно для таких случаев создали объявления using (using declaration) , псевдонимы пространства имен (namespace aliases) и typedef.
namespace aliases и typedef имеют одинаковую семантику , они создают синонимы/псевдонимы(aliases) , альтернативные имена для типов (смотреть ПРИМ).Это полезно для сокращения длинных имен пространств, особенно когда они вложены.В то время как using declaration , просто делает имя доступным напрямую в локальной области.
Пример:
namespace A{
namespace B{
namespace C{
class Type;
}
}
}
using A::B::C::Type; // <- using declaration
using Type = A::B::C::Type;// <- namespace aliases
typedef A::B::C::Type Type;// <- typedefТеперь наш Type может напрямую использоваться в пространстве имен где мы их написали.Важно отметить что при использования typedef с шаблонами могут появится трудности, а вот с namespace aliases - нет,aliases в таких случаях может быть проще и читабельнее.ПРИМ: Отличие typedef и namespace aliases - typedef работает только с типами, а не с пространствами имен.

