2014-04-11 24 views

risposta

18

Il & è un qualificatore di riferimento. I qualificatori Ref sono nuovi in ​​C++ 11 e non ancora supportati in tutti i compilatori, quindi non li vedi spesso al momento. Si specifica che questa funzione può essere richiamata solo su lvalue (e non su rvalues):

#include <iostream> 

class kitten 
{ 
private: 
    int mood = 0; 

public: 
    void pet() & 
    { 
     mood += 1; 
    } 
}; 

int main() 
{ 
    kitten cat{}; 
    cat.pet(); // ok 

    kitten{}.pet(); // not ok: cannot pet a temporary kitten 
} 

In combinazione con il cv-qualificazione const, significa che è possibile chiamare questa funzione solo utente su lvalue, e quelli possono essere costanti.

+4

Si potrebbe aggiungere che questa è una nuova funzionalità in C++ 11, non ancora supportata da tutti i compilatori e che non è probabile per vederlo nel codice esistente (ancora). –

+3

La rilevanza di questa costruzione è che proibisce cose come 'Beta_ab const & danger = Beta_ab(). GetAB();' –

+0

OK, vedo. Quindi, se supportato dal compilatore, questo dovrebbe essere impostato su ogni funzione membro const che restituisce un riferimento const a una variabile membro? Ho un sacco di questi e occasionalmente ho avuto bug relativi al loro utilizzo su un valore. – galinette

3

Sappiamo che in questo codice ...

Beta_ab const& getAB() const { return ab; } 
         ^^^^^ 

Il evidenziato const significa che la funzione membro può essere chiamato un oggetto const. Una funzione membro può sempre essere chiamata su un oggetto non-const indipendentemente dalla qualifica cv della funzione.

Quindi, in questo codice ...

Beta_ab const& getAB() const & { return ab; } 
          ^

Dovremmo aspettarci che l'evidenziata & dice anche qualcosa su ciò che i tipi di oggetti di questa funzione membro è permesso di essere chiamato in causa. Saremmo corretti; in C++ 11, questo dice che la funzione membro può essere chiamata solo su lvalue.

Beta_ab const& getAB() const& { return ab; } 
Beta_ab &&  getAB() &&  { return ab; } 

Nell'esempio precedente, il primo overload viene richiamato lvalue, e la seconda di sovraccarico viene richiamato non const rvalues. Simile al seguente esempio più familiare, con qualificazioni applicati ai parametri delle funzioni ordinarie:

void setAB(AB const& _ab) { ab = _ab; } 
void setAB(AB &&  _ab) { ab = std::move(_ab); } 

funziona in modo leggermente diverso per i parametri ordinari se, come in questo esempio, il primo overload avrebbe accettato un rvalue se il secondo overload sono stati rimossi .

Problemi correlati