Aliasy
Można użyć deklaracji aliasu, aby zadeklarować nazwę do wykorzystywania jako synonim wcześniej zadeklarowanego typu. (Mechanizm ten jest także zwany nieformalnie jako alias typu).Można także używać tego mechanizmu do tworzenia szablonu aliasu, który może być szczególnie użyteczny w przypadku niestandardowych alokatorów.
using identifier = type;
Uwagi
identifier
Nazwa aliasu.type
Identyfikator typu, dla którego tworzony jest alias.
Alias nie wprowadza nowego typu i nie może zmienić znaczenie istniejącej nazwy typu.
Najprostsza forma aliasu jest równoważna z mechanizmem typedef z C++03:
// C++11
using counter = long;
// C++03 equivalent:
// typedef long counter;
Oba umożliwiają tworzenie zmiennych typu "licznik".Bardziej użyteczny jest alias typu takiego, jak ten dla std::ios_base::fmtflags:
// 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);
Aliasy działają również z wskaźnikami funkcji, ale znacznie bardziej czytelnie niż odpowiednik 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;
Ograniczeniem mechanizmów typedef jest brak możliwości pracy z szablonami.Jednak składnia aliasu typu w C++11 umożliwia tworzenie szablonów aliasów:
template<typename T> using ptr = T*;
// the name 'ptr<T>' is now an alias for pointer to T
ptr<int> ptr_int;
Przykład
W poniższym przykładzie zademonstrowano sposób użycia szablonu aliasu z niestandardowym alokatorem — w tym przypadku, typu wektora całkowitego.Można zastąpić dowolny typ typem int, aby wygodnie tworzyć alias pozwalający ukryć złożone parametry list w kodzie głównych funkcjonalności.Wykorzystując niestandardowy alokator w całym kodzie, można poprawić czytelność i zmniejszyć ryzyko wprowadzenia błędów spowodowanych przez błędy pisowni.
#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;
}