Question

S'il vous plaît prendre en compte les trois fonctions.

std::string get_a_string()
{
    return "hello";
}

std::string get_a_string1()
{
    return std::string("hello");
}

std::string get_a_string2()
{
    std::string str("hello");
    return str;
}
  1. Est-ce que RVO appliquer dans tous les trois cas?
  2. Est-ce OK pour revenir un comme temporaire dans le code ci-dessus? Je crois qu'il est OK puisque je rentrais par la valeur plutôt que de retourner une référence.

Toutes les pensées?

Était-ce utile?

La solution

Dans deux premiers cas de l'optimisation RVO aura lieu. RVO est ancienne fonctionnalité et la plupart des compilateurs soutient. Le dernier cas est appelé ainsi NRVO (nommé RVO). C'est relativement nouvelle fonctionnalité de C ++. Standard permet, mais ne nécessite pas la mise en œuvre de NRVO (ainsi que RVO), mais certains compilateurs supporte.

Vous pouvez en savoir plus sur RVO au point 20 du livre Scott Meyers Plus efficace C ++. 35 nouvelles façons d'améliorer vos programmes et conceptions .

est un bon article sur NRVO dans Visual C ++ 2005.

Autres conseils

D'abord, il est tout à fait correct de retourner une valeur temporaire qui est ce que vous faites. Elle est copiée et que l'original sera hors de portée de la copie ne sera pas le faire et peut être utilisé en toute sécurité par l'appelant.

En second lieu, les trois cas sont en fait identiques (puisque vous ne lisez pas le temporaire dans le troisième cas de toute façon) et un compilateur peut même émettre le même code pour tous. Par conséquent, il peut utiliser RVO dans les trois cas. Ceci est entièrement dépendant du compilateur.

Tous les cas sont corrects. Ils ont tous construiront un temporaire et appliquer le constructeur de copie du type de retour. Nécessairement, s'il n'y a pas de constructeur de copie, le code échouera.

RVO se passera sur les trois cas sous la plupart des compilateurs. La seule différence est le dernier où la norme ne force pas. Cela parce que vous avez une variable nommée. Mais la plupart des compilateurs sont assez intelligents pour appliquer RVO à elle encore ... la suite de la variable nommée est déclarée et les transformations moins elle est appliquée à, les meilleures cotes pour RVO à appliquer à une variable nommée.

Par ailleurs, le retour d'une référence est bien sûr possible que vous pourriez avoir vu dans un autre code. Ce que vous ne devez pas faire est de renvoyer une référence t un objet local.

std::string& get_a_string2()
{
    std::string str("hello");
    return str; //error!
}

Cela produira une erreur de compilation, comme vous le savez. Cependant,

std::string& get_a_string2(std::string& str)
{
    // do something to str
    return str; //OK
}

fonctionne très bien. En ce cas, il n'y a pas de construction de la construction ou la copie en question. Il suffit de la fonction renvoie une référence à son argument.

  1. Cela dépend de votre compilateur - quelle plate-forme vous parlez? La meilleure façon de le savoir est de compiler une très petite application de test et vérifiez l'ASM votre compilateur produit.

  2. Oui, il est OK, même si vous ne mentionnez ce que vous êtes sur le point en question; la vitesse? style? vous pouvez un local temporaire à une référence const - la durée de vie du temporaire sera étendue à la durée de vie de la référence - l'essayer et voir par vous-même! (Herb Sutter exaplins cette

scroll top