Type alias, alias template (since C++11)
L'alias de type est un nom qui fait référence à un type précédemment défini (similaire à
typedef
).
L'alias de modèle est un nom qui fait référence à une famille de types.
Table des matières |
Syntaxe
Les déclarations d'alias sont des déclarations avec la syntaxe suivante :
using
identifiant
attr
(optionnel)
=
type-id
;
|
(1) | ||||||||
template
<
template-parameter-list
>
|
(2) | ||||||||
template
<
template-parameter-list
>
requires
constraint
|
(3) | (depuis C++20) | |||||||
| attr | - | séquence facultative d'un nombre quelconque d' attributs |
| identifier | - | le nom introduit par cette déclaration, qui devient soit un nom de type (1) soit un nom de template (2) |
| template-parameter-list | - | liste de paramètres de template , comme dans la déclaration de template |
| constraint | - | une expression de contrainte qui restreint les paramètres de template acceptés par ce template d'alias |
| type-id | - | déclarateur abstrait ou tout autre type-id valide (qui peut introduire un nouveau type, comme indiqué dans type-id ). Le type-id ne peut pas faire référence directement ou indirectement à identifier . Notez que le point de déclaration de l'identifiant se situe au point-virgule suivant type-id . |
Explication
template<class T> struct Alloc {}; template<class T> using Vec = vector<T, Alloc<T>>; // type-id est vector<T, Alloc<T>> Vec<int> v; // Vec<int> est identique à vector<int, Alloc<int>>
Lorsque le résultat de la spécialisation d'un alias template est un template-id dépendant, les substitutions ultérieures s'appliquent à ce template-id :
template<typename...> using void_t = void; template<typename T> void_t<typename T::foo> f(); f<int>(); // erreur, int n'a pas de type imbriqué foo
Le type produit lors de la spécialisation d'un alias template ne peut pas utiliser directement ou indirectement son propre type :
template<class T> struct A; template<class T> using B = typename A<T>::U; // type-id est A<T>::U template<class T> struct A { typedef B<T> U; }; B<short> b; // erreur : B<short> utilise son propre type via A<short>::U
Les alias templates ne sont jamais déduits par la déduction d'argument de template lors de la déduction d'un paramètre template template.
Il n'est pas possible de partiellement ou explicitement spécialiser un alias template.Comme toute déclaration de template, un alias template ne peut être déclaré qu'au niveau de la portée de classe ou de la portée de namespace.
|
Le type d'une expression lambda apparaissant dans une déclaration de template d'alias est différent entre les instanciations de ce template, même lorsque l'expression lambda n'est pas dépendante. template<class T> using A = decltype([] {}); // A<int> and A<char> refer to different closure types |
(depuis C++20) |
Notes
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_alias_templates
|
200704L
|
(C++11) | Alias templates |
Mots-clés
Exemple
#include <iostream> #include <string> #include <type_traits> #include <typeinfo> // alias de type, identique à // typedef std::ios_base::fmtflags flags; using flags = std::ios_base::fmtflags; // le nom 'flags' désigne maintenant un type : flags fl = std::ios_base::dec; // alias de type, identique à // typedef void (*func)(int, int); using func = void (*) (int, int); // le nom 'func' désigne maintenant un pointeur vers une fonction : void example(int, int) {} func f = example; // alias de modèle template<class T> using ptr = T*; // le nom 'ptr<T>' est maintenant un alias pour pointeur vers T ptr<int> x; // alias de type utilisé pour masquer un paramètre de modèle template<class CharT> using mystring = std::basic_string<CharT, std::char_traits<CharT>>; mystring<char> str; // un alias de type peut introduire un typedef membre template<typename T> struct Container { using value_type = T; }; // qui peut être utilisé en programmation générique template<typename ContainerT> void info(const ContainerT& c) { typename ContainerT::value_type T; std::cout << "ContainerT is `" << typeid(decltype(c)).name() << "`\n" "value_type is `" << typeid(T).name() << "`\n"; } // alias de type utilisé pour simplifier la syntaxe de std::enable_if template<typename T> using Invoke = typename T::type; template<typename Condition> using EnableIf = Invoke<std::enable_if<Condition::value>>; template<typename T, typename = EnableIf<std::is_polymorphic<T>>> int fpoly_only(T) { return 1; } struct S { virtual ~S() {} }; int main() { Container<int> c; info(c); // Container::value_type sera int dans cette fonction // fpoly_only(c); // erreur : enable_if interdit ceci S s; fpoly_only(s); // correct : enable_if autorise ceci }
Sortie possible :
ContainerT is `struct Container<int>` value_type is `int`
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | S'applique à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| CWG 1558 | C++11 |
la participation des arguments inutilisés dans une spécialisation d'alias
à la substitution n'était pas spécifiée |
la substitution
est effectuée |
Voir aussi
typedef
déclaration
|
crée un synonyme pour un type |
| alias d'espace de noms | crée un alias d'un espace de noms existant |