Aliases
Você pode usar uma declaração de alias para declarar um nome para uso como sinônimo de um tipo declarado anteriormente. (Esse mecanismo também é chamado informalmente de alias de tipo). Você também pode usar esse mecanismo para criar um modelo de alias, o que pode ser particularmente útil para alocadores personalizados.
using identifier = type;
Comentários
identifier
O nome do alias.type
O identificador de tipo para o qual você está criando um alias.
Um alias não introduz um novo tipo e não podem alterar o significado de um nome de tipo existente.
A forma mais simples de alias é equivalente ao mecanismo typedef de C++03:
// C++11
using counter = long;
// C++03 equivalent:
// typedef long counter;
Os dois permitem a criação de variáveis do tipo “counter”. Algo mais útil seria um alias de tipo para std::ios_base::fmtflags como este:
// C++11
using fmtfl = std::ios_base::fmtflags;
// C++03 equivalent:
// typedef std::ios_base::fmtflags fmtfl;
fmtfl fl_orig = std::cout.flags();
fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex;
// ...
std::cout.flags(fl_hex);
Os aliases também funcionam com ponteiros de função, mas são muito mais legíveis que o equivalente de typedef:
// C++11
using func = void(*)(int);
// C++03 equivalent:
// typedef void (*func)(int);
// func can be assigned to a function pointer value
void actual_function(int arg) { /* some code */ }
func fptr = &actual_function;
Uma restrição do mecanismo typedef é que ele não funciona com modelos. No entanto, a sintaxe de alias de tipo no C++11 permite a criação de modelos de alias:
template<typename T> using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> ptr_int;
Exemplo
O exemplo a seguir demonstra como usar um modelo de alias com um alocador personalizado – nesse caso, um tipo de vetor de inteiro. Você pode substituir qualquer tipo por int para criar um alias conveniente para ocultar as listas de parâmetros complexas em seu código funcional principal. Ao usar o alocador personalizado em todo o seu código, você pode melhorar a legibilidade e reduzir o risco de introduzir bugs causados por erros de digitação.
#include <stdlib.h>
#include <new>
template <typename T> struct MyAlloc {
typedef T value_type;
MyAlloc() { }
template <typename U> MyAlloc(const MyAlloc<U>&) { }
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
T * allocate(const size_t n) const {
if (n == 0) {
return nullptr;
}
if (n > static_cast<size_t>(-1) / sizeof(T)) {
throw std::bad_array_new_length();
}
void * const pv = malloc(n * sizeof(T));
if (!pv) {
throw std::bad_alloc();
}
return static_cast<T *>(pv);
}
void deallocate(T * const p, size_t) const {
free(p);
}
};
#include <vector>
using MyIntVector = std::vector<int, MyAlloc<int>>;
#include <iostream>
int main ()
{
MyIntVector foov = { 1701, 1764, 1664 };
for (auto a: foov) std::cout << a << " ";
std::cout << "\n";
return 0;
}