2012-04-15 16 views
6

Test.hoperator == i lista :: 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 
} 

Program nie będzie kompilować ze względu na myList.remove() :

1> c: \ program pliki (x86) \ microsoft wizualne studio 10,0 \ vc \ include \ list (1194): error C2678: binary '==': nie znaleziono operatora, który przyjmuje lewy operand typu 'std :: tr1 :: weak_ptr < _Ty>' (lub nie ma akceptowalnego konwersji) 1>
z 1> [1> _Ty = int 1>]

Ale widać następująco określonej w Test.h:

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

na czym polega problem?

+0

nie jesteś pewien, ale czy możesz spróbować zdefiniować operator bool == z odniesieniami do stałych? – CharlesB

+0

Ups, miałem to w ten sposób pierwotnie i zapomniałem go zmienić. Ten sam problem z odniesieniami do stałych. – user987280

Odpowiedz

6

Przeciążenie operatora zostanie znaleziony przez argument-dependent lookup, a funkcja nie ma zastosowania, ponieważ nie jest zdefiniowane w przestrzeni nazw std (przestrzeni nazw typów argumentów i kontekście wypowiedzi wewnątrz std::list::remove).

Powinieneś użyć remove_if, aby zastosować niestandardową funkcję predykatu. Ogólnie nie należy definiować operatorów dla typów wewnątrz bibliotek, których nie można modyfikować.

+0

Chyba masz na myśli 'std :: remove' i' std :: remove_if'. Twój link wydaje się nigdzie nie wskazywać. – Fraser

+0

@Fraser naprawiony, dzięki – Potatoswatter

+0

Świetnie, dzięki za informacje. Chciałbym tego uniknąć całkowicie, ale muszę usunąć z listy weak_ptrs. Czy byłoby złym pomysłem zdefiniowanie operatora == wewnątrz przestrzeni nazw std? Użyłem tylko remove_if z jednoargumentowym predykatem z samym elementem jako argumentem. Musiałbym porównać element ze wskaźnikiem, który próbuję usunąć. Czy można wywołać predykat z drugim argumentem? – user987280