如果您没有实现清理方法并且定期使用它,那么拥有一组弱引用指针是一个糟糕的想法。您可能希望在比较函数中加入保护措施,因为目前结果未定义。例如,采纳@PiotrNycz的建议:
template <class T>
struct wptr_less_than
{
bool operator() ( const std::weak_ptr<T>& lhs, const std::weak_ptr<T>& rhs ) const {
return lhs.expired() || (!rhs.expired() && *lhs.lock() < *rhs.lock());
}
};
计算有效的弱指针
使用count_if
和weak_ptr::expired
的组合:
template <class T, class C, class A>
size_t count_valid_pointers( const std::set< std::weak_ptr<T>, C, A >& s )
{
return s.size() - std::count_if( s.begin(), s.end(),
[]( const std::weak_ptr<T>& wptr ){ return wptr.expired(); }
);
}
查找特定值的元素
您可以使用静态共享指针来存储查询(虽然这有点丑陋):
template <class T, class C, class A>
typename std::set< std::weak_ptr<T>, C, A >::iterator
find_value( const std::set< std::weak_ptr<T>, C, A >& s, const T& val )
{
static auto query = std::make_shared<T>();
query.reset( const_cast<T*>(&val), []( T* ){} ) ;
return s.find(query);
}
还有一个例子:
#include <algorithm>
#include <iostream>
#include <memory>
#include <set>
template <class T>
struct wptr_less_than
{
bool operator() ( const std::weak_ptr<T>& lhs, const std::weak_ptr<T>& rhs ) const {
return lhs.expired() || (!rhs.expired() && *lhs.lock() < *rhs.lock());
}
};
template <class T, class C, class A>
size_t count_valid_pointers( const std::set< std::weak_ptr<T>, C, A >& s )
{
return s.size() - std::count_if( s.begin(), s.end(),
[]( const std::weak_ptr<T>& wptr ){ return wptr.expired(); }
);
}
template <class T, class C, class A>
typename std::set< std::weak_ptr<T>, C, A >::iterator
find_value( const std::set< std::weak_ptr<T>, C, A >& s, const T& val )
{
static auto query = std::make_shared<T>();
query.reset( const_cast<T*>(&val), []( T* ){} ) ;
return s.find(query);
}
int main()
{
std::set< std::weak_ptr<int>, wptr_less_than<int> > intset;
auto a = std::make_shared<int>(1);
auto b = std::make_shared<int>(2);
intset.insert(a); intset.insert(b); a.reset();
std::cout << "intset size:" << intset.size() << std::endl;
std::cout << "intset real size:" << count_valid_pointers(intset) << std::endl;
if ( find_value(intset,2) != intset.end() )
std::cout << "Found it!\n";
}
size()
不够用了吗? - gsamarassize()
可以给出总数,但我想知道是否存在特定的一个。而intset.count(make_shared<int>(1))
并没有像我预期的那样工作。我以为它应该返回1。 - Kayweak_ptr
的本质是它不持有所指对象的所有权,而只持有一个共同控制块的所有权。使用make_shared
时,该控制块与对象在同一连续内存区域中,但这并不重要:当没有真正的shared_ptr
引用该对象时,该对象在逻辑上已经不存在了。 - Cheers and hth. - Alflhs.lock()
可以返回一个空的std::shared_ptr
。 - Galik