web-dev-qa-db-fra.com

Les affectations de type «auto» d'un pointeur en c ++ 11 nécessitent-elles «*»?

Étant donné que ma variable est un pointeur, si je l'affecte à une variable de type "auto", dois-je spécifier le "*"?

std::vector<MyClass> *getVector(); //returns populated vector
//...

std::vector<MyClass> *myvector = getVector();  //assume has n items in it
auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

//goal is to behave like this assignment:
std::vector<MyClass> *newvar3 = getVector();

Je suis un peu confus sur la façon dont ce auto fonctionne en c ++ 11 (c'est une nouvelle fonctionnalité de c ++ 11, non?)

Mise à jour: J'ai révisé ce qui précède pour mieux clarifier la façon dont mon vecteur est vraiment rempli dans une fonction, et j'essaie simplement d'assigner le pointeur renvoyé à une variable. Désolé pour la confusion

43
Dolan Antenucci
auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

Les deux sont identiques et déclarent un pointeur sur std::vector<MyClass> (pointant vers un emplacement aléatoire, car myvector n'est pas initialisé dans votre exemple et contient probablement des déchets). Donc, fondamentalement, vous pouvez utiliser n'importe lequel d'entre eux. Je préférerais auto var = getVector(), mais vous pouvez opter pour auto* var = getVector() si vous pensez que cela met l'accent sur l'intention (que var est un pointeur) mieux.

Je dois dire que je n'ai jamais rêvé d'une incertitude similaire en utilisant auto. Je pensais que les gens utiliseraient simplement auto sans y penser, ce qui est correct 99% du temps - la nécessité de décorer auto avec quelque chose vient uniquement avec des références et des qualificatifs cv.

Cependant, il y a est une légère différence entre les deux quand il est légèrement modifié:

auto newvar1 = myvector, newvar2 = something;

Dans ce cas, newvar2 Sera un pointeur (et quelque chose doit l'être aussi).

auto *newvar1 = myvector, newvar2 = something;

Ici, newvar2 Est le type de pointe, par exemple. std::vector<MyClass>, Et l'initialiseur doit être adéquat.

En général, si l'initialiseur n'est pas une liste d'initialiseurs contreventés, le compilateur traite auto comme ceci:

  1. Il produit une déclaration de modèle de fonction artificielle avec un argument de la forme exacte du déclarant, avec auto remplacé par le paramètre de modèle. Donc pour auto* x = ..., Il utilise

    template <class T> void foo(T*);
    
  2. Il essaie de résoudre l'appel foo(initializer) et regarde ce qui est déduit pour T. Cela est remplacé à la place de auto.

  3. S'il y a plus de déclarants dans une seule déclaration, cela est fait pour chacun d'eux. Le T déduit doit être le même pour tous ...

43
jpalecek
auto newvar1 = *myvector;

C'est probablement ce que vous voulez, ce qui crée une copie du vecteur réel. Si vous souhaitez avoir une référence à la place, écrivez auto& newvar1 = *myvector; ou pour créer un autre pointeur vers le même vecteur, utilisez auto newvar1 = myvector;. La différence par rapport à votre autre tentative auto *newvar1 = myvector; est que ce dernier force myvector à être de type pointeur, donc le code suivant échoue:

std::vector<int> v1;
auto* v2 = v1; // error: unable to deduce ‘auto*’ from ‘v1’
2
Stacker