Jestem trochę zdezorientowany, czy i kiedy powinienem używać typedef w C ++. Uważam, że to balansuje pomiędzy czytelnością a klarownością.
Oto przykładowy kod bez żadnych typedefs:
int sum(std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last)
{
static std::map<std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator>,
int> lookup_table;
std::map<std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator>, int>::iterator lookup_it =
lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
Dość brzydka IMO. Dodam więc kilka funkcji typedef do funkcji, aby wyglądała ładniej:
int sum(std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last)
{
typedef std::tuple<std::vector<int>::const_iterator,
std::vector<int>::const_iterator> Lookup_key;
typedef std::map<Lookup_key, int> Lookup_table;
static Lookup_table lookup_table;
Lookup_table::iterator lookup_it = lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
Kod jest wciąż nieco niezręczny, ale pozbywam się większości koszmarów. Ale wciąż istnieją iteratory wektorów int, ten wariant pozbywa się tych:
typedef std::vector<int>::const_iterator Input_iterator;
int sum(Input_iterator first, Input_iterator last)
{
typedef std::tuple<Input_iterator, Input_iterator> Lookup_key;
typedef std::map<Lookup_key, int> Lookup_table;
static Lookup_table lookup_table;
Lookup_table::iterator lookup_it = lookup_table.find(lookup_key);
if (lookup_it != lookup_table.end())
return lookup_it->second;
...
}
Wygląda to czysto, ale czy nadal jest czytelne?
Kiedy powinienem użyć typedef? Jak tylko mam typ koszmaru? Jak tylko pojawi się więcej niż jeden raz? Gdzie mam je umieścić? Czy powinienem ich używać w sygnaturach funkcji, czy zachować do implementacji?
typedef Input_iterator std::vector<int>::const_iterator;
jest odwrotnie
#define
nie jest wystarczająco dobry.