2014-11-13 3 views
14

:만료 된 weak_ptr과 초기화되지 않은 weak_ptr을 구별 할 수 있습니까? 예

std::weak_ptr<int> wp1(std::make_shared<int>()); 
std::weak_ptr<int> wp2; 

assert(PointsToValidOrExpiredObject(wp1)); 
assert(!PointsToValidOrExpiredObject(wp2)); 

이러한 기능 가능한가?

사용 사례 : 클래스의 생성자는 std::weak_ptr<Foo>을 종속으로 사용합니다. 만료 된 객체를 전달하는 것은 괜찮습니다 (특정 워크 플로에서 발생할 수 있음). 그러나 null을 전달하면 프로그래머가 무언가를 잊어 버린 것을 의미합니다. 이것을 생성자의 매개 변수 유효성 검사의 일부로 테스트하고 싶습니다.

+0

['expired()'] (http://en.cppreference.com/w/cpp/memory/weak_ptr/expired) 메소드를 살펴 보았습니까? – Borgleader

+0

@ 보글 리더. 예 - 불행히도 두 경우 모두 true를 반환합니다. – dlf

+1

대답이있는 것처럼 보일 수도 있지만 덜 비약적 인 해결책은 비어 있지 않은 공유 포인터로만 구성 할 수있는 유형의 약한 포인터를 래핑하고 미처리 포인터가 아닌 필요로하는 것일 수 있습니다. –

답변

16

std::weak_ptr::owner_before은 비어 있고 만료 된 약한 포인터를 구별 할 수 있습니다.

template <typename T> 
bool PointsToValidOrExpiredObject(const std::weak_ptr<T>& w) { 
    return w.owner_before(std::weak_ptr<T>{}) || 
      std::weak_ptr<T>{}.owner_before(w); 
} 

Demo : 당신은 그러므로으로 PointsToValidOrExpiredObject 구현할 수 있습니다.

Regarding the original uncertainty I had about an expired weak_ptr still maintaining ownership : 라이브러리 전체의 스레드 안전 요구 사항에 따라 만료 된 weak_ptr의 소유권이 동일하게 유지되도록해야합니다. 그렇지 않으면 스레드 A에서 마지막으로 남은 shared_ptr을 삭제하면 해당 shared_ptr과 함께 소유권을 공유하는 1/some/all weak_ptr의 상태를 관찰 가능하게 수정해야합니다. 스레드 B가 같은 weak_ptr의 상태를 동시에 검사했다면 일반적으로 금지 된 라이브러리 구현에 의해 도입 된 데이터 경쟁이 발생합니다.

+0

그건 사실 인 것처럼 보입니다. 포인터는 "소유권을 공유하거나 둘 다 비어있는 경우"와 동일하며 만료되면 약한 포인터가 비어있는 것을 나타내지 않고 소유권을 공유하지 않습니다. –

+1

좋아요! 나는 이것이 의미하는 것과 그것이 왜 작동하는지 이해하기 위해'owner_before' 문서를 찾아야 만했다. 같은 상황에있는 다른 사람들을 위해서 :이 함수는 실제로 연산자를 사용하는 <연산자와 같은 것이라고 생각할 수 있습니다. 따라서이 dlf