Méně známé skutečnosti o C++: Aliasy na prostory jmen

Od Petr Zemek, 2013-07-28

O možnosti vytváření aliasů na typy pomocí konstrukce typedef ví zřejmě každý programátor v C a C++. Co je však méně známé, tak je, že v C++ si můžete vytvářet aliasy na jmenné prostory. Tento příspěvek vám ukáže, jak na to a vysvětlí, k čemu se to může hodit.

Úvod aneb kde typedef nestačí

Pokud máte složitý typ, např.

std::map<std::string, std::set<std::string> >

tak se vám pro zpřehlednění kódu může vyplatit si udělat typový alias. K tomu slouží konstrukce typedef:

typedef std::set<std::string> StringSet;
typedef std::map<std::string, StringSet> NameToNicknamesMap;

Co když ale používáte složitě zanořené prostory jmen? Např. chcete používat různé třídy z fslibrary::filesystem::io:

fslibrary::filesystem::io::input_stream istream("file1.txt");
fslibrary::filesystem::io::output_stream ostream("file2.txt");

Většina lidí vám doporučí použít using direktivu či deklaraci. Pokud jste si ale vědomi problémů, do kterých se použitím using můžete dostat (zaneřádění jmenných prostorů a další), budete se pídit po jiném řešení. Co takto použít typedef? Zní to slibně, ale pokud to zkusíte, tak narazíte, protože ten funguje pouze pro typy, nikoliv pro prostory jmen.

Naše záchrana: aliasy na prostory jmen

C++ nám již od ISO C++98 umožňuje používat tzv. aliasy na prostory jmen (angl. namespace aliases). Jejich syntaxe je následující:

namespace alias_name = some_long_namespace;

Výše uvedený kód bychom tedy mohli přepsat takto:

namespace fsio = fslibrary::filesystem::io;
fsio::input_stream istream("file1.txt");
fsio::output_stream ostream("file2.txt");

Pokud používáte mnoho tříd z onoho jmenného prostoru, bude výsledné řešení mnohem čitelnější.

K čemu je to ještě dobré?

Jak jsme již viděli, hodí se to v případě, kdy chcete zjednodušit a zpřehlednit kód, aniž byste se zapletli do možných problémů vyplývajících s použití using direktivy/deklarace. Je ještě jiné možné použití? Představte si, že máte dvě různé implementace souboru tříd: jedna implementace podporuje vícevláknové zpracování, ta druhá ne. Pak můžete v kódu, který tyto třídy využívá používat jediný prostor jmen (alias) a někde mít umístěný následující kód, kterým vám vybere vhodný alias v závislosti na podpoře vícevláknového zpracování:

#if THREADS_ARE_SUPPORTED_ON_THE_PLATFORM
namespace mylib = myproject::mylibrary::impl_with_threads;
#else
namespace mylib = myproject::mylibrary::impl_without_threads;
#endif

Dále vám v kódu stačí využívat mylib:: a nemusíte se starat o to, zda jsou na dané platformě podporována vlákna či nikoliv.

Další čtení

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
12 + 7 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.