Qu'est-ce que la déclaration
return {};
en C ++ 11 indiquer, et quand l'utiliser au lieu de (par exemple)
return NULL;
ou
return nullptr;
Qu'est-ce que la déclaration
return {};
en C ++ 11 indiquer, et quand l'utiliser au lieu de (par exemple)
return NULL;
ou
return nullptr;
return {};
indique "retour d'un objet de la fonction de type de retour de la initialisé avec un vide à la liste de l'initialiseur". Le comportement exact dépend de l'objet renvoyé est de type.
À partir de cppreference.com (parce que l'OP est étiqueté C++11, je l'ai exclu les règles en C++14 et C++17; voir le lien pour plus de détails):
- Si l'embrassa-init-la liste est vide et T est un type de classe avec un constructeur par défaut, la valeur d'initialisation est effectuée.
- Sinon, si T est un type d'agrégation, agrégée d'initialisation est effectuée.
- Sinon, si T est une spécialisation de std::initializer_list, la T de l'objet est direct-initialisé ou copier-initialisé, en fonction du contexte, de l'arc-boutée-init-liste.
Sinon, les constructeurs de T sont considérés, en deux phases:
- Tous les constructeurs qui prennent std::initializer_list comme seul argument, ou comme premier argument si les arguments restants ont des valeurs par défaut, sont examinés et mis en rapport par la surcharge de résolution contre un seul argument de type std::initializer_list
- Si l'étape précédente n'est pas de produire un match, tous les constructeurs de T participer à la résolution de surcharge à l'encontre de l'ensemble des arguments qui se compose des éléments de l'arc-boutée-init-liste, avec la restriction que seuls les non-réduire les conversions sont autorisées. Si cette étape produit un constructeur explicite comme le meilleur match pour une copie de la liste d'initialisation, la compilation échoue (remarque, dans un simple copier-initialisation explicite les constructeurs ne sont pas pris en considération).
Sinon (si T n'est pas un type de classe), si l'embrassa-init-liste a un seul élément et T n'est pas une référence de type ou d'un type de référence qui est compatible avec le type de l'élément, T est direct-initialisé (en direct de la liste d'initialisation) ou copier-initialisé (en copie de la liste d'initialisation), sauf que la réduction de conversions ne sont pas autorisés.
- Sinon, si T est un type de référence qui n'est pas compatible avec le type de l'élément. (cela échoue si la référence est un non-const lvalue de référence)
- Sinon, si l'embrassa-init-liste n'a pas d'éléments, T est la valeur d'initialisation.
Avant C++11, pour une fonction retournant un std::string
, vous auriez écrit:
std::string get_string() {
return std::string();
}
À l'aide de l'attache de la syntaxe en C++11, vous n'avez pas besoin de répéter le type:
std::string get_string() {
return {}; // an empty string is returned
}
return NULL
et return nullptr
doit être utilisée lorsque la fonction retourne un pointeur de type:
any_type* get_pointer() {
return nullptr;
}
Toutefois, NULL
est obsolète depuis C++11, car il est juste un alias à une valeur entière (0), tandis que l' nullptr
est un véritable type de pointeur:
int get_int() {
return NULL; // will compile, NULL is an integer
}
int get_int() {
return nullptr; // error: nullptr is not an integer
}
return {};
signifie qu' {}
est l'initialiseur de la valeur de retour. La valeur de retour est la liste initialisée avec une liste vide.
Voici quelques informations générales sur la valeur de retour, sur la base de [stmt.de retour dans la Norme C++:
Pour une fonction qui renvoie en valeur (c'est à dire le type de retour n'est pas une référence et pas void
), il est un objet temporaire appelé la valeur de retour. Cet objet est créé par l' return
déclaration, et son initialiseurs dépendent de ce qui était dans l'instruction de retour.
La valeur de retour survit jusqu'à la fin de la pleine expression dans le code qui appelle la fonction; si elle a le type de classe, puis de son destructeur fonctionnera, sauf si elle a durée de vie prolongée par l'appelant de la liaison d'une référence directement à elle.
La valeur de retour peut être initialisée de deux façons différentes:
return some_expression;
- la valeur de retour est la copie initialisé à partir d' some_expression
return { possibly_empty_list };
- la valeur de retour est
liste initialisée à partir de la liste.En supposant T
est de retour de la fonction type, puis notez qu' return T{};
est différent d' return {}
: dans le premier cas, un temporaire T{}
est créé, puis la valeur de retour est de copier-initialisé dès que temporaire.
Cela ne parviennent pas à compiler si T
n'a pas de accessible copier/déplacer-constructeur, mais return {};
réussira même si ces constructeurs ne sont pas présents. En conséquence, return T{};
peut montrer les effets secondaires du constructeur par copie, etc., bien que ce soit une copie élision contexte, il ne peut pas.
Voici un bref récapitulatif de la liste d'initialisation en C++14 (N4140 [dcl.init.liste]/3), où l'initialiseur est une liste vide:
T
est un agrégat, ensuite, chaque membre est initialisé à partir de son corset ou égal initialiseur si il en a un, sinon comme si, en {}
(donc appliquer ces étapes de manière récursive).T
est un type de classe avec un utilisateur par défaut fourni par le constructeur, constructeur est appelé.T
est un type de classe avec un implicitement défini, ou = default
ed constructeur par défaut, l'objet est initialisé à zéro , puis le constructeur par défaut est appelé.T
est std::initializer_list
, la valeur de retour est un vide, une telle liste.T
est un non-type de classe -- des types de retour ne peut pas être des tableaux), la valeur de retour est initialisé à zéro. Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.