为什么weak_ptr没有比较运算符==?

4
如果我有一个vector<weak_ptr<Type>>,我不能使用vector::erase(remove())来移除所需的weak_ptr,因为它没有一个比较运算符==。
必须向remove_if传递一个lambda谓词,用于比较通过weak_ptr::_Get()访问的基础原始指针,以便在vector::erase(remove_if())中删除。 _Get()以下划线和大写字母开头,这意味着它是为实现保留的,不应该由用户访问。
很明显weak_ptr不应该以这种方式存储,但为什么呢?
我正在考虑使用vector<weak_ptr<>>在管理类中只有一些需要进一步处理的对象的子类中保存weak_ptr,并通过lock()确保它们在多线程应用程序中未被管理类删除。
管理器会通知子类对象的创建和删除,使vector<weak_ptr<>>保持最新。

1
你会期望 == 比较什么?相同的 weak_ptr?还是不同的 weak_ptr 指向同一个对象?或者是指向不同对象但值相同的 weak_ptr - Galik
相关链接:https://dev59.com/I2ct5IYBdhLWcg3wKqUd,其中包含一个指向http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1590.html的链接。 - Barmar
可能是Equality-compare std::weak_ptr的重复问题。 - Joseph D.
2
你的谓词应该使用 a.lock() == b.lock(),而不是依赖于内部实现细节。 - Igor Tandetnik
1
@GemTaylor 所有过期的句柄都是相同的。没有(标准,可移植)方法可以将它们区分开来;它们不会跟踪其来源。如果您认为需要它,请在weak_ptr实例旁边保留某种形式的它。 - Igor Tandetnik
显示剩余6条评论
1个回答

0

您可以使用带有显式谓词的擦除-删除惯用法。

例如:

#include <functional>
#include <iostream>
#include <memory>
#include <vector>

using std::cout;
using std::make_shared;
using std::remove_if;
using std::vector;
using std::weak_ptr;

int main()
{
  auto p7 = make_shared<int>(7);
  auto p8 = make_shared<int>(8);
  auto p10 = make_shared<int>(10);
  auto p11 = make_shared<int>(11);

  vector<weak_ptr<int>> v;

  v.push_back(p7);
  v.push_back(p8);

  {
    auto p9 = make_shared<int>(9);
    v.push_back(p9);
    // p9 dtor'd here
  }

  v.push_back(p10);
  v.push_back(p11);
  p8.reset(new int{18}); // old p8 dtor'd here
  p10 = make_shared<int>(110); // old p10 dtor'd here

  // Only 7 and 11 left.

  v.erase(remove_if(v.begin(), v.end(), [](auto w){ if (auto spt = w.lock()) return false; else return true; }), v.end() );
  for (auto w : v)
  {
    cout << "Value is ";
    if (auto s = w.lock())
    {
      cout << *s << "\n";
    }
    else
    {
      cout << "MISSING!\n";
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接