所以我有一個std::vector<std::shared_ptr<T>> myListOfT;
,我有一個std::weak_ptr<T> ptrToOneT;
是從用來填充該容器的指針之一創建的(比如我在回調函數中使用它)。該容器上的std::find
和我的weak_ptr
會給我一個原始shared_ptr
的迭代器(如果集合中存在這樣的一個)?它在標準的某個地方有保證還是依賴於這個實現?對象std :: shared_ptr是否可以通過它的std :: weak_ptr找到?
回答
std::weak_ptr::lock()
是你如何「促進」一個weak_ptr
到shared_ptr
:
std::weak_ptr<T> ptrToOneT;
auto observe = ptrToOneT.lock();
if (observe) {
// observe now shares ownership of the one T
}
else {
// there is no managed object or it has already
// been destroyed
}
如果lock()
成功,那麼你有一個正常的std::shared_ptr<T>
,你可以用它來find()
就像你在一個容器中的任何其他對象。雖然你可能不需要find()
,因爲你已經擁有了它(除非你想要erase()
它或某物)。
側面說明,有shared_ptr
,它不是真正意義指的是「原shared_ptr
」
我們可以逃脫不使用std::weak_ptr::owner_before
鎖定weak_ptr
。我將使用一個稍微詳細的解決方案不是必要的,並介紹owner_equal
,這是對口std::owner_less
:
template<typename T>
class owner_equal
{
private:
template<typename L, typename R>
static bool e(L const& l, R const& r)
{ return !(l.owner_before(r)) && !(r.owner_before(l)); }
public:
using S = std::shared_ptr<T>;
using W = std::weak_ptr<T>;
bool operator()(S const& l, W const& r) const { return e(l, r); }
bool operator()(W const& l, S const& r) const { return e(l, r); }
};
使用此功能的對象類型,我們可以自定義std::find_if
:
using T = int;
std::vector<std::shared_ptr<T>> myListOfT =
{std::make_shared<int>(0), std::make_shared<int>(1), std::make_shared<int>(2)};
int const pos = 1;
std::weak_ptr<T> ptrToOneT = myListOfT[pos];
auto pred = [&ptrToOneT](std::shared_ptr<T> const& e)
{ return owner_equal<T>{}(e, ptrToOneT); };
auto const r = std::find_if(begin(myListOfT), end(myListOfT), pred);
assert(r - begin(myListOfT) == pos);
拉姆達可以通過結合表達代替,例如:
auto pred = std::bind(owner_equal<T>{}, std::cref(ptrToOneT),
std::placeholders::_1);
@davidhigh建議的優化:
template<typename FwdIt, typename T>
FwdIt findWeakPtr(FwdIt b, FwdIt e, std::weak_ptr<T> const& w)
{
if(w.expired()) return e;
else
{
auto pred = [&w](std::shared_ptr<T> const& e)
{ return owner_equal<T>{}(e, w); };
return std::find_if(b, e, pred);
}
}
(未測試)
這也稍有變化的行爲:如果weak_ptr
是 「空」 的,例如已經從空的shared_ptr
或通過默認的ctor創建,它將通過owner_equal
比較任何空的shared_ptr
。但是,在這種情況下是正確的。因此,優化後的版本不會在該範圍內找到空的共享指針。
應該在範圍內找到空的共享指針嗎?
考慮:
using T = int;
std::vector<std::shared_ptr<T>> myListOfT =
{std::shared_ptr<T>(), std::shared_ptr<T>()};
int const pos = 1;
std::weak_ptr<T> ptrToOneT = myListOfT[pos];
auto const r = my_weak_ptr_find(begin(myListOfT), end(myListOfT), ptrToOneT);
auto const r_pos = r - begin(myListOfT);
空的共享指針相等。因此,如果您允許查找空的共享指針,則可以使用r_pos != pos && r != end(myListOfT)
。例如,此答案中的算法的第一個版本產生r_pos == 0
。
有關其他背景,請參閱:
我在自己的代碼前幾天也有類似的問題。根據我的SO研究,可以做你所要求的。鎖定弱指針,如果共享指針沒有過期,然後用std::find
struct A{};
int main()
{
std::vector<std::shared_ptr<A> > sptr_vec;
std::weak_ptr<A> wptr;
if(auto sptr = wptr.lock())
{
auto it = std::find(std::begin(sptr_vec), std::end(sptr_vec), sptr);
if (it != std::end(sptr_vec))
{
std::cout<<"found"<<std::endl;
}
}
}
注意的是,C++標準本身並不在這裏,有關 - 共享三分球的比較的心臟比較所包含的原始指針,即存儲器中的地址。
或者,如果你有弱指針的載體,可以使用std::find_if
與在飛行中鎖定了一個謂語:
std::vector<std::weak_ptr<A> > wptr_vec;
std::shared_ptr<A> sptr;
auto it = std::find_if(std::begin(wptr_vec), std::end(wptr_vec)
, [&sptr](auto const& w){ auto s = w.lock();
if (s) {return s == sptr;}
return false; });
if (it != std::end(wptr_vec))
{
std::cout<<"found"<<std::endl;
}
注意FOT這個應用程序,我會考慮的nullptr
等效與本身,即nullptr == nullptr
是true
,因爲不需要。因此,我從謂詞(也從第一個代碼塊中的搜索中)排除了這種情況。
編輯:只是認爲owner_lock
解決方案@dyp,這是有利的,如果它只是關於搜索。
- 1. 通過std :: weak_ptr刪除一個對象
- 2. std :: bind和std :: weak_ptr
- 3. Doxygen可以識別std :: shared_ptr或std :: map
- 4. std :: tr1 :: shared_ptr是否互斥?
- 5. std :: map with std :: weak_ptr key
- 6. std :: enable_if和std :: shared_ptr
- 7. std :: shared_ptr與std容器
- 8. 是否通過了weak_ptr
- 9. 將std :: shared_ptr傳遞給std :: thread的函數對象
- 10. C++ std :: vector <std :: shared_ptr>
- 11. C++ 11:將std :: is_pointer擴展到std :: shared_ptr
- 12. 的std :: shared_ptr的雙回調
- 13. 是否可以創建* CCAnimation對象的std :: map?
- 14. std :: enable_shared_from_this ...是否有一個新的shared_ptr知道從shared_from_this()?
- 15. 在shared_ptr重置後,weak_ptr是否總是過期?
- 16. C++ 0x std :: shared_ptr與boost :: shared_ptr
- 17. 我可以定義從std :: function到std :: shared_ptr的隱式轉換<MyClass>?
- 18. std :: shared_ptr的用法
- 19. QCache和std :: shared_ptr的
- 20. 是否可以通過Microsoft RPC傳遞std :: string?
- 21. C++中std :: unique_ptr和std :: shared_ptr的區別
- 22. 比較兩套std :: weak_ptr
- 23. C++:是否可以從std :: string對象中分離char *指針?
- 24. 如何處理不斷髮展的C++ std :: namespace?例如:std :: tr1 :: shared_ptr vs. std :: shared_ptr vs. boost :: shared_ptr vs. boost :: tr1 :: shared_ptr
- 25. C++中的空std :: shared_ptr與空std :: shared_ptr有什麼區別?
- 26. 動態分配的shared_ptr是否可以通過它正在管理的對象的dtor刪除它自己?
- 27. 「刪除此」到一個分配了std :: shared_ptr的對象?
- 28. 通過使用std :: get,std :: tuple_size,std :: tuple_element
- 29. std :: shared_ptr迭代器
- 30. 可以std :: async調用std :: function對象嗎?
簡短回答是肯定的,但在進行比較之前,您可能需要將'get()'返回的值轉換爲絕對基址指針。 –
用'weak_ptr :: lock()'獲得'shared_ptr',然後將它傳遞給'std :: find'。你會發現一些指向同一個對象的指針。 –
另外,通過鎖定,可以防止weak_ptr指向的對象被刪除,例如,引用計數變爲零。在另一個線程中。 –