Domanda

C++03 §4.2 N°1:
Un valore lvalue o rvalue di tipo "matrice di N T" o "matrice di limite sconosciuto di T" può essere convertito in un valore r di tipo "puntatore a T". Il risultato è un puntatore al primo elemento della matrice.

Ciò che mi ha confuso per molto tempo in questa affermazione è che non capivo bene cosa significherebbe un valore di tipo array.Cioè, non sono riuscito a trovare un'espressione il cui tipo fosse un array e il risultato fosse un rvalue.Leggo Questo thread, che sostanzialmente pone la stessa domanda e la risposta accettata è "no, non esiste un valore di tipo array".Penso che potrei avere una contraddizione in questo.

C++03 §5.2.5 N°4: (si tratta dell'espressione E1.E2)
Se E2 è un membro dati non statico e il tipo di E1 è "cq1 vq1 X" e il tipo di E2 è "cq2 vq2 T", l'espressione designa il membro denominato dell'oggetto designato dalla prima espressione.Se E1 è un lvalue, allora E1.E2 è un lvalue.

Presumo che altrimenti si tratti di un rvalue (a condizione che E2 non sia un riferimento, quel caso è coperto da §5.2.5 N°3) e quindi...

struct A
{
   int a[4];
};
A f()
{
   A a;
   return a; 
}
int main()
{
   f().a; //I think this is an rvalue of array type...
}

Vedo due opzioni qui:
Opzione 1: Ho ragione, evviva, sì, fantastico.In questo caso la domanda è:ci sono altri esempi?
Opzione 2: Mi sbaglio, in questo caso la domanda è:è un difetto dello standard?

Non conosco 1, ma dubito davvero di 2 perché quando parlano di conversioni da funzione a puntatore menzionano solo i valori dei tipi di funzione (ovviamente apprezzando che non ci siano valori di tali).Quindi è molto probabile che abbiano pensato ai valori dei tipi di array.

Quindi, fondamentalmente la mia domanda è se ho trovato o meno un esempio di rvalue di tipo array e, in caso contrario, fornirne uno valido, che credo fermamente esista.

È stato utile?

Soluzione

Sì hai ragione.L'espressione è un valore di tipo array.Questo non è un difetto: il comitato lo sa, ed era anche un problema comune in C89, che consente solo la conversione in puntatori per lvalue di tipi di array.Di conseguenza, non è possibile indicizzare o dereferenziare un array come f().a.C99 ha risolto questo problema e C++ non ha problemi con esso.

Si noti che il fatto che si tratti o meno di un valore è indipendente dal fatto che l'espressione denoti o meno un oggetto.C++03 ha accidentalmente omesso di dire che un'espressione rvalue di tipo array denota un oggetto.Questo problema è stato risolto in C++0x da DR#450.

(ovviamente apprezzando che non ci siano valori di questo tipo)

In realtà ci sono valori dei tipi di funzione.Questi si verificano per le funzioni membro non statiche indicate da un'espressione di accesso ai membri della classe

struct A { void f(); };

/* A().f is an rvalue of type "void()" */
int main() { A().f(); }

Altri suggerimenti

La A è un valore.L'array al suo interno non lo è.Immagina il caso in cui hai una catena di metodi su quell'oggetto temporaneo: le variabili al suo interno vivono per più di una chiamata e ritorno del metodo e possono passare riferimenti (validi per la durata della catena) ad altre funzioni.Tali funzioni non possono sapere in anticipo che verranno richiamate su un valore.

Nell'ultima versione della bozza, puoi sovraccaricare le funzioni su rvalue/lvalue *this.Tuttavia, anche in questo caso, un riferimento a rvalue non crea il contenuto di ciò che viene riferito a un rvalue, e non sono del tutto sicuro che QUALSIASI compilatore attualmente lo supporti, e so che MSVC no.

Infatti, utilizzando decltype, puoi determinare facilmente che il compilatore chiama quell'array un lvalue.

Prendere in considerazione:

template<typename A, typename B> auto sum(A&& a, B&& b) -> decltype(std::forward<A>(a) + std::forward<B>(b)) {
    return std::forward<A>(a) + std::forward<B>(b);
}

Questo è lo scopo di decltype e distingue sicuramente tra lvalues ​​e rvalues.In alternativa, considera questo:

int main()
{
    auto var = f().a;
}

Var è un int*.Si tratta di un fallimento immediato, poiché f().a muore immediatamente.Non sono sicuro della mia opinione immediata al riguardo, ma certamente non è valido per un valore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top