2015-05-15 15 views
24

considerare this question, che è circa il seguente codice non compilazione:gli operatori possono essere dichiarati come amici non-template terzi

std::vector<int> a, b; 
std::cout << (std::ref(a) < std::ref(b)); 

Esso non viene compilato perché il vettore comparison operators per vector sono funzione non-membro i modelli e le conversioni implicite non possono essere considerati. Tuttavia, se gli operatori sono stati invece scritti come non membro non-modello, friend funzioni:

template <class T, class Allocator = std::allocator<T>> 
class vector { 
    // ... 

    friend bool operator<(const vector& lhs, const vector& rhs) { 
     // impl details 
    } 
}; 

Allora questa versione di operator< sarebbe stato trovato da ADL ed è stato scelto come il migliore di sovraccarico vitale, e l'esempio originale avrei compilato Dato che, c'è un motivo per preferire il modello di funzione non membro che abbiamo attualmente, o dovrebbe essere considerato un difetto nello standard?

+0

Ci sono problemi simili con l'operatore << 'e gli stream in alcuni punti: il che porta a qualcosa. Posso scrivere un 'template operator << (std :: basic_ostream &, std :: basic_string &)' * senza * a seconda di più di una dichiarazione di avanti (di entrambi) due. Un "operatore Koenig" richiederebbe almeno uno di essi (quale?), Richiede entrambi? (questo è tangente, poiché riguarda gli operatori di due tipi, non uno come sopra) – Yakk

+3

Non vedo perché dovresti scrivere 'std :: ref (a) Columbo

+0

@Columbo Funziona con 'int's. Inoltre, non so perché tu possa mai fare un sacco di cose - non significa che il linguaggio non lo permetta. Inoltre, questo permetterebbe alla tua classe con 'operator std :: string()' di fare confronti con le cose a confronto di 'string's. – Barry

risposta

1

Dato che, c'è un motivo per preferire la funzione modello non membro che attualmente abbiamo, o questo dovrebbe essere considerato un difetto nella norma?

Il motivo è se ADL potrebbe scoprire la funzione corretta oppure no. Quando tale ricerca richiede di estrarre i parametri del modello sostituito dal tipo di oggetto dato e quindi di sostituirli più volte in un parametro basato su modello del modello di funzione, ADL non può farlo perché non ci sono motivi nel caso generale di preferire un modo per i parametri del modello che si legano ad altri. Il modello di funzione non membro definito dopo ma sempre nello spazio dei nomi di tale modello (a causa di friend) esclude tale indeterminazione.

Problemi correlati