2012-04-15 7 views
6

Test.hOperator == und Liste :: 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 
} 

Das Programm wird nicht aufgrund myList.remove kompilieren() :

1> c: \ Programme (x86) \ Microsoft Visual Studio 10.0 \ vc \ include \ list (1194): Fehler C2678: binary '==': Kein Operator gefunden, der einen linken Operanden vom Typ 'std :: tr1 :: weak_ptr < _Ty>' (oder es gibt keine akzeptablen Konvertierung) 1>
mit 1> [1> _Ty = int 1>]

Aber Sie können folgende Definition in Test.h sehen:

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

Was ist das Problem?

+0

nicht sicher, aber können Sie versuchen, den bool-Operator == mit const-Referenzen zu definieren? – CharlesB

+0

Hoppla, ich hatte es ursprünglich so und habe vergessen es wieder zu ändern. Dasselbe Problem mit Const-Referenzen. – user987280

Antwort

6

Der Betreiber Überlastung wird durch argument-dependent lookup gefunden, und Ihre Funktion gilt nicht, da es nicht im Namensraum std (Namensraum der Argumenttypen und Kontext des Ausdrucks in std::list::remove) definiert ist.

Sie sollten remove_if verwenden, um eine benutzerdefinierte Prädikatfunktion anzuwenden. Versuchen Sie im Allgemeinen nicht, Operatoren für Typen in Bibliotheken zu definieren, die Sie nicht ändern können.

+0

Ich denke du meinst 'std :: remove' und' std :: remove_if'. Außerdem scheint Ihr Link nirgends zu zeigen. – Fraser

+0

@Fraser fest, danke – Potatoswatter

+0

Großartig, danke für die Info. Ich möchte das ganz vermeiden, aber ich muss aus einer Liste von weak_ptrs entfernen. Wäre es eine schlechte Idee, operator == inside namespace std zu definieren? Ich habe nur remove_if mit einem unären Prädikat mit dem Element selbst als Argument verwendet. Ich müsste das Element mit dem Zeiger vergleichen, den ich entfernen möchte. Ist es möglich, das Prädikat mit einem zweiten Argument aufzurufen? – user987280