Estou um pouco confuso sobre se e quando devo usar typedef em C ++. Eu sinto que é um ato de equilíbrio entre legibilidade e clareza.
Aqui está um exemplo de código sem nenhum 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;
...
}
OMI muito feio. Então, adicionarei alguns typedefs dentro da função para torná-la mais agradável:
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;
...
}
O código ainda é um pouco desajeitado, mas me livrei da maioria dos materiais de pesadelo. Mas ainda existem os iteradores de vetor int, essa variante se livra deles:
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;
...
}
Parece limpo, mas ainda é legível?
Quando devo usar um typedef? Assim que eu tiver um tipo de pesadelo? Assim que ocorre mais de uma vez? Onde devo colocá-los? Devo usá-los em assinaturas de funções ou mantê-los na implementação?
typedef Input_iterator std::vector<int>::const_iterator;está ao contrário
#definenão é bom o suficiente.