2012-04-15 16 views
6

Test.hoperatore == e list :: remove()

#ifndef TEST_H 
#define TEST_H 

#include <memory> 

template <class Type> 
bool operator==(const std::weak_ptr<Type>& wp1, const std::weak_ptr<Type>& wp2) 
{ 
std::shared_ptr<Type> sp1; 

if(!wp1.expired()) 
    sp1 = wp1.lock(); 

std::shared_ptr<Type> sp2; 

if(!wp2.expired()) 
    sp2 = wp2.lock(); 

return sp1 == sp2; 
} 

#endif 

Test.cpp

#include "Test.h" 
#include <list> 


int main() 
{ 
typedef std::list< std::weak_ptr<int> > intList; 

std::shared_ptr<int> sp(new int(5)); 
std::weak_ptr<int> wp(sp); 

intList myList; 
myList.push_back(wp); 

myList.remove(wp); //Problem 
} 

Il programma non verrà compilato a causa di myList.remove() :

1> c: \ programmi (x86) \ microsoft studio visivo 10.0 \ vc \ include \ list (1194): errore C2678: binario '==': nessun operatore trovato che prende un operando a sinistra di tipo 'std :: tr1 :: weak_ptr < _Ty>' (o non è accettabile conversione) 1>
con 1> [1> _Ty = int 1>]

Ma si può visualizzare il seguente definito in Test.h:

bool operator==(const std::weak_ptr<Type>& wp1, const std::weak_ptr<Type>& wp2) 

Qual è il problema?

+0

non sicuro, ma si può provare a definire l'operatore bool == con riferimenti const? – CharlesB

+0

Whoops, l'avevo originariamente in quel modo e ho dimenticato di cambiarlo di nuovo. Lo stesso problema con i riferimenti const. – user987280

risposta

6

L'overload dell'operatore viene rilevato da argument-dependent lookup e la funzione non è applicabile in quanto non è definita nello spazio dei nomi std (lo spazio dei nomi dei tipi di argomento e il contesto dell'espressione all'interno di std::list::remove).

È necessario utilizzare remove_if per applicare una funzione di predicato personalizzata. In generale, non tentare di definire gli operatori per i tipi all'interno di librerie che non è possibile modificare.

+0

Immagino tu intenda 'std :: remove' e' std :: remove_if'. Inoltre, il tuo collegamento sembra non puntare da nessuna parte. – Fraser

+0

@Fraser risolto, grazie – Potatoswatter

+0

Grande, grazie per le informazioni. Vorrei evitare tutto questo, ma ho bisogno di rimuovere da un elenco di weak_ptrs. Sarebbe una cattiva idea definire l'operatore == all'interno dello spazio dei nomi std? Ho usato remove_if con un predicato unario solo con l'elemento stesso come argomento. Avrei bisogno di confrontare l'elemento con il puntatore che sto cercando di rimuovere. È possibile chiamare il predicato con un secondo argomento? – user987280