2016-01-01 32 views

risposta

33

Le dichiarazioni sono esattamente equivalenti. auto funziona (quasi) come template type deduction. Mettere la stella in modo esplicito rende il codice un po 'più facile da leggere e rende il programmatore consapevole del fatto che bar2 è un puntatore.

5

Non ha importanza per quanto riguarda l'interpretazione del codice C++; puoi scrivere quello che vuoi Tuttavia, c'è una questione di stile e leggibilità: in generale, non devi nascondere i qualificatori di puntatori, riferimenti e CV, e forse anche i puntatori intelligenti, in alias di tipi, poiché rende più difficile per il lettore capire che è ciò che sta accadendo. Gli alias di tipo dovrebbero includere il contenuto di tipo semanticamente rilevante, mentre i qualificatori e i modificatori dovrebbero rimanere visibili. Così preferiscono la seguente:

using Foo = long_namespace::Foobrigation<other_namespace::Thing>; 
using MyFn = const X * (int, int); 

std::unique_ptr<Foo> MakeThatThing(MyFn & fn, int x) // or "MyFn * fn" 
{ 
    const auto * p = fn(x, -x); 
    return p ? p->Create() : nullptr; 
} 

E non dire:

using PFoo = std::unique_ptr<Foo>; // just spell it out 
using MyFn = int(&)(int, int);  // unnecessary; & is easy to spell 
auto p = fn(x, -x);     // Don't know that p is a pointer 

Si noti inoltre che le qualificazioni di riferimento (a differenza di puntatori) cambiare veramente il tipo di variabile che viene dichiarato, quindi non sono facoltativo:

X & f(); 
auto a = f(); // copy! 
auto & b = f(); // b is the same as the return value of f() 

Infine, l'aggiunta di qualifiche esplicite del puntatore const può essere d'aiuto nella cost-correttezza. Considera il prossimo esempio, in cui un contenitore contiene puntatori a mutevole, ma abbiamo solo bisogno dell'accesso const. Basta auto * sarebbe dedurre un puntatore ad mutevole, che possiamo evitare dicendo const esplicitamente:

std::vector<X*> v = /* ... */; 
for (const auto * p : v) 
{ 
    observe(p->foo()); // no need for a mutable *p 
} 
+0

Come 'MyFn' tipo restituito è' int', 'Auto * p = fn (x, -x)' si può essere compilato (grazie a '*, altrimenti dovremmo aspettare' p-> Crea() 'per l'errore) :-). – Jarod42

+0

@ Jarod42: Sì, stavo usando troppo poche entità diverse. Fisso. –

14

In questo esempio specifico sia bar1 e bar2 sono gli stessi. È una questione di preferenze personali, anche se direi che bar2 è più facile da leggere.

Tuttavia, questo non vale per i riferimenti come si vede in questo example:

#include <iostream> 
using namespace std; 

int main() { 
    int k = 10; 
    int& foo = k; 
    auto bar = foo; //value of foo is copied and loses reference qualifier! 
    bar = 5; //foo/k won't be 5 
    cout << "bar : " << bar << " foo : " << foo << " k : " << k << endl; 
    auto& ref = foo; 
    ref = 5; // foo/k will be 5 
    cout << "bar : " << bar << " foo : " << foo << " k : " << k; 
    return 0; 
} 
35

Utilizzando auto * "documenti intenzione". E auto *p = expr; può essere dedotto correttamente solo se expr restituisce il puntatore. Esempio:

int f(); 

auto q = f(); // OK 

auto *p = f(); // error: unable to deduce 'auto*' from 'f()' 
+0

Buon punto sul divieto di deduzione senza puntatori, con aumento di frequenza. – vsoftco

+2

Sì, ma l'operatore successivo è sovraccarico per restituire un puntatore smart notnull o const propagating e quindi auto * si interrompe. –

10

Come altri hanno detto, genereranno lo stesso codice. L'asterisco è il rumore di linea (e rende più difficile passare da puntatori grezzi a puntatori intelligenti se, ad esempio,viene sostituito da &foo). Se vuoi essere esplicito, allora con tutti i mezzi, essere esplicito; ma quando si utilizza l'inferenza di tipo, lascia che il compilatore faccia il suo lavoro. La mancanza di asterischi non implica che un oggetto non sia un puntatore.

+3

Penso che il commento tra parentesi meriti maggiore enfasi. Anche nei semplici esempi forniti da altri, l'aggiunta di '*' può rendere il codice più leggibile, ma può rendere più difficile la manutenzione. Personalmente ritengo che il vantaggio principale di "auto" sia facilitare la manutenzione, ancor più che ridurre la digitazione o aumentare la leggibilità. – ToddR

8

C'è una grande differenza quando si utilizza const qualificazioni:

int i; 

// Const pointer to non-const int 
const auto ip1 = &i; // int *const 
++ip1; // error 
*ip1 = 1; // OK 

// Non-const pointer to const int 
const auto* ip2 = &i; // int const* 
++ip2; // OK 
*ip2 = 1; // error