Veuillez considérer ce code. J'ai vu ce type de code plusieurs fois. words
est un vecteur local. Comment est-il possible de le renvoyer depuis une fonction?
Pouvons-nous garantir qu'il ne mourra pas?
std::vector<std::string> read_file(const std::string& path)
{
std::ifstream file("E:\\names.txt");
if (!file.is_open())
{
std::cerr << "Unable to open file" << "\n";
std::exit(-1);
}
std::vector<string> words;//this vector will be returned
std::string token;
while (std::getline(file, token, ','))
{
words.push_back(token);
}
return words;
}
std::vector<std::string>&
Réponses:
Tant qu'aucune référence n'est renvoyée, c'est parfaitement bien de le faire.
words
sera déplacé vers la variable recevant le résultat.La variable locale sera hors de portée. après avoir été déplacé (ou copié).
la source
Pré C ++ 11:
La fonction ne renverra pas la variable locale, mais plutôt une copie de celle-ci. Votre compilateur peut cependant effectuer une optimisation où aucune action de copie réelle n'est effectuée.
Voir cette question et réponse pour plus de détails.
C ++ 11:
La fonction déplacera la valeur. Voir cette réponse pour plus de détails.
la source
Je pense que vous faites référence au problème en C (et C ++) selon lequel le retour d'un tableau à partir d'une fonction n'est pas autorisé (ou du moins ne fonctionnera pas comme prévu) - c'est parce que le retour du tableau sera (si vous l'écrivez dans le formulaire simple) renvoie un pointeur vers le tableau réel sur la pile, qui est ensuite rapidement supprimé lorsque la fonction est renvoyée.
Mais dans ce cas, cela fonctionne, car le
std::vector
est une classe et les classes, comme les structures, peuvent (et seront) copiées dans le contexte des appelants. [En fait, la plupart des compilateurs optimiseront ce type particulier de copie en utilisant quelque chose appelé "Optimisation de la valeur de retour", spécialement introduit pour éviter de copier des objets volumineux lorsqu'ils sont renvoyés par une fonction, mais c'est une optimisation, et du point de vue des programmeurs, cela va se comportent comme si le constructeur d'affectation était appelé pour l'objet]Tant que vous ne renvoyez pas de pointeur ou de référence à quelque chose qui se trouve dans la fonction de retour, tout va bien.
la source
Pour bien comprendre le comportement, vous pouvez exécuter ce code:
Le résultat est le suivant:
Notez que cet exemple a été fourni dans un contexte C ++ 03, il pourrait être amélioré pour C ++> = 11
la source
Je ne suis pas d'accord et ne recommande pas de retourner un
vector
:C'est beaucoup plus rapide:
J'ai testé sur Visual Studio 2017 avec les résultats suivants en mode version:
8.01 MOPs par référence
5.09 MOPs renvoyant le vecteur
En mode débogage, les choses sont bien pires:
0,053 MOPS par référence
0,034 MOP par vecteur de retour
la source
C'est en fait un échec de conception. Vous ne devriez pas utiliser de valeur de retour pour tout ce qui n'est pas une primitive pour tout ce qui n'est pas relativement trivial.
La solution idéale doit être implémentée via un paramètre de retour avec une décision sur la référence / le pointeur et l'utilisation correcte d'un "const \ 'y \' ness" comme descripteur.
En plus de cela, vous devez vous rendre compte que l'étiquette sur un tableau en C et C ++ est effectivement un pointeur et que son abonnement est en fait un offset ou un symbole d'addition.
Ainsi, le label ou ptr array_ptr === array label retournant donc foo [offset] signifie vraiment return element à l'emplacement du pointeur mémoire foo + offset du type return type.
la source