Od C++11 přibyly tzv. typové aliasy (using TypeAlias = OriginalType;
). Jedná se o alternativu pro klasický typedef
. V příspěvku uvedu několik důvodů, proč od C++11 na typedef
zapomenout a využívat pouze typové aliasy.
Jak typové aliasy fungují
V C či C++98 se dá alias na jiný typ zavést pomocí typedef
:
typedef OriginalType TypeAlias;
Od C++11 lze vytvořit typový alias taktéž přes klíčové slovo using
:
using TypeAlias = OriginalType;
Obě formy jsou ekvivalentní a není mezi nimi rozdíl [C++14, §7.1.3.2].
Proč od C++11 preferovat typové aliasy
Když mezi nimi není rozdíl, tak proč preferovat using
? Z následujících třech důvodů:
1) using umí vše, co typedef
Jen pro úplnost.
2) using je čitelnější a konzistentní
U using
se název aliasu nachází vždy na stejném místě: za klíčovým slovem using
. U typedef
tomu tak není. Vezměme si např. následující typové aliasy:
typedef unsigned int Size; // Název aliasu je vpravo. typedef std::size_t (*HashFunc)(const MyClass &); // Název aliasu je uprostřed.
U using
je název aliasu vždy vlevo:
using Size = unsigned int; using HashFunc = std::size_t (*)(const MyClass &);
Usnadňuje to orientaci.
3) using zvládá aliasy na šablony lépe, než typedef
S pomocí using
si lze jednoduše vytvořit alias na neúplně specifikovanou šablonu:
// Zavedení typového aliasu. template <typename T> using Dictionary = std::map<std::string, T>; // Použití. Dictionary<int> d;
Toto s pomocí typedef
není možné napsat. Resp. je, ale složitěji a oklikou:
// Zavedení "typového aliasu". template <typename T> struct Dictionary { typedef std::map<std::string, T> type; }; // Použití. Dictionary<int>::type d; // Zde je potřeba uvést '::type'.
Jak vidíme, definice typového aliasu i jeho použití je v případě typedef
složitější a méně čitelné. Navíc, pokud bychom onen alias použili uvnitř jiné šablony, tak u řešení získaného přes typedef
bychom museli použít typename
:
template <typename T> class MyClass { // ... typename Dictionary<T>::type d; // Zde je potřeba 'typename', protože typ '::type' závisí na T. };
Toto u řešení s pomocí using
odpadá:
template <typename T> class MyClass { // ... Dictionary<T> d; };
Od C++11 tedy doporučuji na typedef
zapomenout a používat pouze using
. Používání obou forem zároveň přináší akorát nekonzistenci.
Nadbytečný znak `>'.
Ahoj,
není v
typedef std::map<std::string, T>> type;
navíc znak `>' ?Re: Nadbytečný znak `>'.
Jo jo :). Opravil jsem to. Díky.