Ho questo codiceIl compilatore pensa che "A (A &)" accetta rvalues per un momento?
struct A { A(); A(A&); };
struct B { B(const A&); };
void f(A);
void f(B);
int main() {
f(A());
}
Con mia grande sorpresa questo non funziona con GCC e Clang. Clang dice per esempio
Compilation finished with errors:
source.cpp:8:10: error: no matching constructor for initialization of 'A'
f(A());
^~~
source.cpp:1:21: note: candidate constructor not viable: expects an l-value for 1st argument
struct A { A(); A(A&); };
^
source.cpp:1:16: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
struct A { A(); A(A&); };
^
source.cpp:4:13: note: passing argument to parameter here
void f(A);
perché scelgono il primo f
, quando la seconda f
funziona bene? Se rimuovo il primo f
, la chiamata ha esito positivo. Che cosa è più strano per me, se io uso l'inizializzazione brace, funziona anche bene
int main() {
f({A()});
}
Tutti chiamano il secondo f
.
Grazie! Non riesco a trovare nessuna regola per il caso '{...}'. Questo spiega perché il caso '{...}' funziona? –
@ JohannesSchaub-litb: Non sono sicuro, tbh, stai chiamando la funzione con un _braced-init-list_ così le regole sono decisamente diverse. –
@ JohannesSchaub-litb Vedere [over.ics.list]. Penso che abbia a che fare con [over.ics.ref]/3 (ho interpretato male il tuo codice in precedenza): quando si forma il sottoinsieme di funzioni vitali, il ctor 'A (A &)' non è considerato vitale in quanto lega un riferimento temporaneo a un valore non costante. – dyp