std :: owner_less做什么?

时间:2018-11-08 22:51:17

标签: c++

我已经读过std :: owner_less执行“基于所有者而不是基于值”的排序,如果两个智能指针“指向同一对象的子对象”,它们是等效的-究竟是什么意思? / p>

作为测试用例,我编写了以下代码:

struct T {};

int main() {
    T* t = new T();

    std::shared_ptr<T> a(t);
    std::shared_ptr<T> b(t);

    std::set<std::shared_ptr<T>> set1;
    set1.insert(a);
    std::cout << set1.size() << std::endl;
    set1.insert(b);
    std::cout << set1.size() << std::endl;

    std::set<std::shared_ptr<T>, std::owner_less<std::shared_ptr<T>>> set2;
    set2.insert(a);
    std::cout << set2.size() << std::endl;
    set2.insert(b);
    std::cout << set2.size() << std::endl;
}

输出为1 1 12。在我看来,如果std :: owner_less执行“基于所有者的”比较,则不应将a和b视为相同,而默认比较器会将它们视为不同?我的代码的结果似乎是相反的。

1 个答案:

答案 0 :(得分:4)

std::shared_ptr<T> a(t);
std::shared_ptr<T> b(t);

shared_ptr被销毁时,这是未定义的行为;这两个shared_ptr不知道彼此的存在,它们将尝试删除t


owner_less可以被认为是“在(真实或隐喻)控制块的地址上排序”。因此,如果它们共享所有权或都为空,则认为等效的两个shared_ptr(和weak_ptr):

struct T { int x, y; };

std::shared_ptr<T> a(new T{});
std::shared_ptr<T> b = a;

std::shared_ptr<int> c(a, &a->y); // aliasing constructor

std::shared_ptr<T> d(a.get(), [](T*){}); // null deleter to avoid no double delete
std::shared_ptr<T> e(std::shared_ptr<T>(), a.get()); // "non-owning" empty shared_ptr with a non-null stored pointer
根据{{​​1}},

abc都是等效的,因为它们共享所有权。 owner_less不与d共享所有权(它具有自己的“控制块”),因此根据a的不同。同样,对于owner_less,它为空(什么也不拥有),但存储的指针为非null。

默认比较器仅比较存储的指针或e。它将看到get()abd都是等效的,而e则是不同的(假设您将双方都转换为{{1} },以便它们具有可比性。)