Prendendo l'indirizzo di un oggetto temporaneo
Domanda
§5.3.1 Operatori unari, Sezione 3
Il risultato dell'operatore unario & è un puntatore al suo operando. L'operando sarà un lvalue o un ID qualificato.
Cosa significa esattamente "sarà" in questo contesto?Vuol dire che è un errore prendere l'indirizzo di un temporaneo?Me lo stavo solo chiedendo, perché g++ mi dà solo un avviso, mentre comeau si rifiuta di compilare il seguente programma:
#include <string>
int main()
{
&std::string("test");
}
g++ avvertimento: taking address of temporary
comeau errore: expression must be an lvalue or a function designator
Qualcuno ha un compilatore Microsoft o altri compilatori e può testare questo programma, per favore?
Soluzione
La parola "deve" nella lingua standard significa un requisito rigoroso. Quindi, sì, il codice è mal-formata (si tratta di un errore) perché tenta di applicare operatore di indirizzo a un non-valore assegnabile.
Tuttavia, il problema qui non è un tentativo di prendere l'indirizzo di un temporaneo . Il problema è, ancora una volta, prendendo indirizzo di un non lvalue . oggetto temporaneo può essere lValue o non Ivalue seconda dell'espressione che produce quel temporaneo o fornisce accesso a quella temporanea. Nel tuo caso hai std::string("test")
- uno stile funzionale cast a un tipo non di riferimento, che per definizione produce un non-valore assegnabile. Quindi l'errore.
Se si volesse prendere l'indirizzo di un oggetto temporaneo, si potrebbe avere aggirato la restrizione in questo modo, ad esempio
const std::string &r = std::string("test");
&r; // this expression produces address of a temporary
whith il puntatore risultante restante valido fino a quando esiste la temporanea. Ci sono altri modi per ottenere legalmente l'indirizzo di un oggetto temporaneo. E 'solo che il metodo specifico sembra essere illegale.
Altri suggerimenti
Quando la parola "si" è utilizzato nella ++ standard C, significa "must sotto pena di morte" -. Se l'applicazione non obbedisce questo, è difettoso
E 'permesso in MSVC con il deprecato / Ze (estensioni abilitati) opzione. E 'stato consentito nelle versioni precedenti di MSVC. Esso genera una diagnostica con tutte le avvertenze abilitati:
avvertimento C4238: estensione non standard utilizzata:. Classe rvalue utilizzato come lvalue
A meno che l'opzione / Za viene utilizzato (rispettare la compatibilità ANSI), allora:
error C2102: '&' richiede l-value
&std::string("test");
chiede l'indirizzo del valore di ritorno della chiamata di funzione (ignoreremo come irrilevante il fatto che questa funzione è un ctor). Non aveva un indirizzo fino a quando si assegna a qualcosa. Quindi si tratta di un errore.
La serie C ++ è un realtà un requisito conformant implementazioni C ++. Nei punti è scritto a distinguere tra il codice che implementazioni conformi devono accettare e il codice per i quali implementazioni conformi devono dare una diagnosi.
Quindi, in questo caso particolare, un compilatore conforme deve dare una diagnosi, se è preso l'indirizzo di un rvalue. Entrambi i compilatori lo fanno, in modo che siano conforme a tale riguardo.
La norma non vieta la generazione di un file eseguibile se una certa ingresso provoca una diagnosi, vale a dire gli avvisi sono la diagnostica validi.
Non sono un esperto di standard, ma suona certamente come un errore per me. g ++ molto spesso dà solo un avvertimento per le cose che sono veramente errori.
conversione definita dall'utente
struct String {
std::string str;
operator std::string*() {
return &str;
}
};
std::string *my_str = String{"abc"};