2013-07-31 20 views
55

Considerando tutte e tre le funzioni, questa chiamata è ambigua.Risoluzione di sovraccarico tra oggetto, riferimento di rval, riferimento const

int f(int); 
int f(int &&); 
int f(int const &); 

int q = f(3); 

Rimozione f(int) cause sia clang e GCC a preferire il riferimento rvalue sopra il riferimento lvalue. Invece rimuovere entrambi i sovraccarichi di riferimento genera ambiguità con f(int).

La risoluzione del sovraccarico viene solitamente eseguita in base a un rigoroso ordine parziale, ma lo int sembra essere equivalente a due cose che non sono equivalenti l'una all'altra. Quali sono le regole qui? Mi sembra di ricordare un rapporto sui difetti al riguardo.

C'è qualche possibilità che lo int && sia preferito rispetto allo int in uno standard futuro? Il riferimento deve essere associato a un inizializzatore, mentre il tipo di oggetto non è così vincolato. Quindi sovraccaricare tra T e T && potrebbe effettivamente significare "utilizzare l'oggetto esistente se mi è stata data la proprietà, altrimenti fare una copia". (Questo è simile al puro pass-by-value, ma risparmia il sovraccarico dello spostamento.) Poiché questi compilatori funzionano attualmente, ciò deve essere eseguito sovraccaricando T const & e T && e copiando esplicitamente. Ma non sono nemmeno sicuro che sia strettamente standard.

+0

stato si' int && 'nel codice, ma poi generalizza a' T && 'nella domanda, nonostante siano diversi. Che cos'è? – Rapptz

+0

@Rapptz Ho solo detto' T' quando parlo di possibili significati nell'uso del mondo reale. suggerire l'inoltro perfetto, questo è un gioco completamente diverso. – Potatoswatter

risposta

43

Quali sono le regole qui?

Poiché v'è un solo parametro, la regola è che uno dei tre inizializzazioni dei parametri vitali di quel parametro deve essere una migliore corrispondenza di sia gli altri due. Quando vengono confrontate due inizializzazioni, l'una è migliore dell'altra o nessuna delle due è migliore (non sono distinguibili).

Senza regole speciali sull'associazione diretta di riferimento, tutte e tre le inizializzazioni menzionate sarebbero indistinguibili (in tutti e tre i confronti).

Le regole speciali sull'associazione di riferimento diretto rendono int&& migliore di const int&, ma nessuna è migliore o peggiore di int. Pertanto non v'è alcuna corrispondenza migliore:

S1 S2 
int int&&   indistinguishable 
int const int& indistinguishable 
int&& const int& S1 better 

int&& è meglio che const int& causa della 13.3.3.2:

S1 e S2 sono bind di riferimento (8.5.3) e non si riferisce ad un parametro oggetto implicito di una funzione membro non statica dichiarata senza un qualificatore ref e S1 associa un riferimento di rvalue a un valore rval e S2 associa un riferimento lvalue.

Ma questa regola non si applica quando una delle inizializzazioni non è un legame di riferimento.

C'è qualche possibilità int & & può essere preferito su int in uno standard futuro? Il riferimento deve essere associato a un inizializzatore, mentre il tipo di oggetto non è così vincolato. Quindi il sovraccarico tra T e T & & potrebbe effettivamente significare "utilizzare l'oggetto esistente se mi è stata data la proprietà, altrimenti fare una copia."

si propone di rendere vincolante una migliore corrispondenza di un non-di riferimento vincolante. Perché non pubblicare il tuo idea di isocpp future proposals un riferimento. SO non è la migliore per il soggettivo discussione/opinione.

+0

Quindi sia gcc che clang hanno ragione: se 'f (int)' e 'f (int &&)' sono in considerazione, il sovraccarico è ambiguo, e lo stesso per 'f (int) 'e' f (int const &) '. – Yakk

+3

@Yakk: _" se f (int) ef (int &&) sono in considerazione, il sovraccarico è ambiguo "_ Quasi. Se non c'è la migliore corrispondenza, il sovraccarico è ambiguo. Supponiamo che 'f (int)', 'f (int &&)' e 'f (double)' siano validi per una chiamata di 'f (2.0)'. 'f (double)' è la migliore corrispondenza anche se 'f (int)' e 'f (int &&)' sono in considerazione. –

Problemi correlati