Je sais qu'en C ++ 11, nous pouvons maintenant utiliser using
pour écrire un alias de type, comme typedef
s:
typedef int MyInt;
D'après ce que je comprends, équivaut à:
using MyInt = int;
Et cette nouvelle syntaxe est née de l'effort pour trouver un moyen d'exprimer " template typedef
":
template< class T > using MyType = AnotherType< T, MyAllocatorType >;
Mais, avec les deux premiers exemples non modèles, y a-t-il d'autres différences subtiles dans la norme? Par exemple, typedef
effectuez un aliasing de manière "faible". C'est-à-dire qu'il ne crée pas un nouveau type mais seulement un nouveau nom (les conversions sont implicites entre ces noms).
Est-ce la même chose using
ou génère-t-il un nouveau type? Y a-t-il des différences?
typedef void (&MyFunc)(int,int);
ouusing MyFunc = void(int,int);
?typedef void MyFunc(int,int);
(ce qui n'a pas l'air aussi mauvais), ouusing MyFunc = void(&)(int,int);
using MyFunc = void(&)(int,int);
? cela signifie-t-ilMyFunc
une référence à une fonction? que faire si vous omettez le & ?typedef void (&MyFunc)(int,int);
. Si vous omettez le&
c'est équivalent àtypedef void MyFunc(int,int);
Réponses:
Ils sont équivalents, du standard (c'est moi qui souligne) (7.1.3.2):
la source
using
mot clé semble être un surensemble detypedef
. Alors, seratypdef
obsolète à l'avenir?using
syntaxe précisément parce que latypedef
sémantique ne fonctionnait pas bien avec les modèles. Ce qui contredit en quelque sorte le fait que l'using
on ait exactement la même sémantique.n1489
. Un alias de modèle n'est pas un alias pour un type, mais un alias pour un groupe de modèles. Faire une distinction entretypedef
le ressenti un besoin de nouvelle syntaxe. En outre, gardez à l'esprit que la question de l'OP concerne la différence entre les versions non modèles.typdef
jamais être déprécié.Ils sont en grande partie les mêmes, sauf que:
la source
typedef
si je peux demander?La syntaxe d' utilisation présente un avantage lorsqu'elle est utilisée dans des modèles. Si vous avez besoin de l'abstraction de type, mais devez également conserver le paramètre de modèle pour pouvoir être spécifié à l'avenir. Vous devriez écrire quelque chose comme ça.
Mais l' utilisation de la syntaxe simplifie ce cas d'utilisation.
la source
Ils sont essentiellement les mêmes mais
using
fournissentalias templates
ce qui est assez utile. Un bon exemple que j'ai pu trouver est le suivant:Donc, nous pouvons utiliser
std::add_const_t<T>
au lieu detypename std::add_const<T>::type
la source
Je sais que l'affiche originale a une excellente réponse, mais pour quiconque tombe sur ce fil comme moi, il y a une note importante de la proposition qui, je pense, ajoute quelque chose de valeur à la discussion ici, en particulier aux préoccupations dans les commentaires sur la question de savoir si le
typedef
mot-clé est va être marqué comme obsolète à l'avenir, ou supprimé pour être redondant / ancien:Pour moi, cela implique une prise en charge continue du
typedef
mot clé en C ++ car il peut encore rendre le code plus lisible et compréhensible .La mise à jour du
using
mot - clé était spécifiquement pour les modèles et (comme cela a été souligné dans la réponse acceptée) lorsque vous travaillez avec des non-modèlesusing
ettypedef
sont mécaniquement identiques, le choix appartient donc entièrement au programmeur pour des raisons de lisibilité et de communication d'intention. .la source
Les deux mots clés sont équivalents, mais il y a quelques mises en garde. La première est que déclarer un pointeur de fonction avec
using T = int (*)(int, int);
est plus clair qu'avectypedef int (*T)(int, int);
. Deuxièmement, la forme d'alias de modèle n'est pas possible avectypedef
. Troisièmement, exposer l'API C nécessiterait destypedef
en-têtes publics.la source
Les déclarations typedef peuvent, contrairement aux déclarations d'alias, être utilisées comme instructions d'initialisation
Bien qu'il s'agisse d'un cas de coin, une déclaration typedef est une instruction init et peut donc être utilisée dans des contextes qui permettent des instructions d'initialisation
alors qu'une alias-declaration n'est pas une instruction init et ne peut donc pas être utilisée dans des contextes qui permettent des instructions d'initialisation
la source