web-dev-qa-db-fra.com

valeur de référence de référence const

Duplicate possible:
comment initialiser les arguments d'une fonction qui sont des classes avec une valeur par défaut

#include <string>

void foo1(const std::string& s = std::string());

void foo2(std::string& s = std::string());

void foo3(const std::string s = std::string());

void foo4(std::string s = std::string());

error at foo2(): default argument for ‘std::string& s’ has type ‘std::string {aka std::basic_string<char>}’

Je comprends le point du compilateur, mais je ne comprends pas comment cela ne s’applique pas non plus à foo1().

15
aiao

Vous ne pouvez pas prendre une référence non-const à un temporaire comme foo2.

Notez que ce ne sont pas spécifiquement des paramètres par défaut. Vous obtenez la même erreur pour les variables de fonction: http://ideone.com/g7Tf7L

#include <string>
using std::string;

#include <iostream>
using std::cout; using std::endl;

int main()
{
    string s1        = string("s1"); // OK, copy it
    const string& s2 = string("s2"); // OK, const reference to it
    string& s3       = string("s3"); // ERROR! non-const reference not allowed!

    cout
            << s1 << ", "
            << s2 << ", "
            << s3 << endl;
    return 0;
}

Lorsque vous prenez une référence const à un temporaire, la durée de vie de la temporaire est étendue à la durée de vie de la référence (§12.2, cité de mon exemplaire de C++ 11 brouillon n3337):

Il existe deux contextes dans lesquels les temporaires sont détruits à un point différent de la fin de l'expression fullex.

...

Le deuxième contexte est celui où une référence est liée à un temporaire. Le temporaire auquel la référence est liée ou le temporaire qui est l'objet complet d'un sous-objet auquel la référence est liée persiste pendant la durée de vie de la référence, sauf:

  • Une liaison temporaire à un membre de référence dans l’initialisateur ctor du constructeur (12.6.2) persiste jusqu’à la sortie du constructeur.
  • Une liaison temporaire à un paramètre de référence dans un appel de fonction (5.2.2) persiste jusqu'à la fin de l'expression complète contenant l'appel.
  • La durée de vie d'une liaison temporaire à la valeur renvoyée dans une instruction return return (6.6.3) n'est pas étendue; le temporaire est détruit à la fin de l'expression complète dans l'instruction return.
  • Une liaison temporaire à une référence dans un nouvel initialiseur (5.3.4) persiste jusqu'à la fin de l'expression complète contenant le nouvel initialiseur.
23
Bill

Cela peut vous surprendre, mais vous pouvez lier la valeur d’une expression temporaire à une constante référence et la durée de vie de l’expression est étendue à celle de la référence. Mais vous ne pouvez pas faire cela avec une référence non constante (lvalue).

3
Kerrek SB

Les déclarations de foo3 et foo4 sont légales car l'argument de ces fonctions n'est pas une référence.

La déclaration de foo2 est illégale car vous ne pouvez pas lier une référence non const à un temporaire.

Alors, pourquoi la déclaration de foo1 est-elle légale? C'est ce qualificatif const très important qui rend cette déclaration légale.

0
David Hammen