Ho provato il seguente codice con GCC, Clang, ICC e VS:È possibile che un riferimento di rval leghi a una funzione?
void f() {}
void g(void (&&)()) { }
int main() {
g(f);
}
Come possiamo vedere, g
prende un riferimento rvalue ma f
è un lvalue e, in generale, i riferimenti rvalue non possono essere tenuti a lvalue . Questo è esattamente ciò ICC lamenta su:
error: an rvalue reference cannot be bound to an lvalue
VS dà anche un errore, ma per un altro motivo:
error C2664: 'void h(void (__cdecl &&)(void))' : cannot convert parameter 1 from 'void (__cdecl *)(void)' to 'void (__cdecl &&)(void)'
Questo mi fa pensare che VS è immediatamente eseguendo un puntatore a funzione a conversione piuttosto che legare direttamente il riferimento a f
. Vale la pena ricordare che se sostituisco g(f)
con g(&f)
, i quattro compilatori producono lo stesso errore.
Infine, GCC e Clang accettano il codice e credo che siano corretti. Mio ragionamento si riferiscono al 8.5.3/5
Un riferimento di tipo “CV1 T1” viene inizializzato da un'espressione di tipo “cv2 T2” come
- Se il riferimento è un riferimento Ivalue [. ..]
- Altrimenti, [...] il riferimento deve essere un riferimento di valore.
- Se l'espressione inizializzatore è una [...] funzione Ivalue [...]
quindi il riferimento è legato al valore della espressione inizializzatore [...]
La mia interpretazione è corretta (che è, Clang e GCC sono conformi per il motivo dato)?
effetti. Ho provato che prima e tutti e quattro i compilatori sono conformi. –
@CassioNeri: OK, grazie per aver condiviso le informazioni –