std :: set of std :: weak_ptr вставить и удалить - PullRequest
1 голос
/ 23 апреля 2020

В моем основном приложении у меня есть std::set<std::shared_ptr<Object>>. Я также хочу создать дополнительный набор std::set<std::weak_ptr<Object>>, потому что я не хочу увеличивать счетчик ссылок, но я также хочу избежать вызова неверных областей памяти с помощью блокировки. К сожалению, я не могу определить std::set с std::weak_ptr s внутри. Сделав это, компилятор жалуется на некоторые ошибки в методах вставки и удаления.

#include <memory>
#include <set>
#include <vector>
class Test{
private:
    int x ;
public:
    Test(int x){
        this->x = x;
    }
    int getx(){
        return x;
    }
};
int main(){
    std::shared_ptr<Test> t = std::make_shared<Test>(10);
    std::weak_ptr<Test> ref = std::weak_ptr<Test>(t);
    std::set<std::weak_ptr<Test>> weakrefs;
    weakrefs.insert(ref);//compiler error
    weakrefs.erase(ref);//compiler error
}

Но когда я использую std::vector<std::weak_ptr<Test>>, мне разрешается вернуться sh назад и вернуться назад. Но я хотел бы, чтобы функциональность была похожа на std::set.

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Чтобы иметь набор weak_ptr с, вам необходим std::owner_less<>, специальный оператор сравнения:

std::set<std::weak_ptr<Test>, std::owner_less<std::weak_ptr<Test>>> weakrefs;

Этот оператор сравнения использует административный регион для поиска интеллектуальных указателей, а не указателей на объект, на который они указывают. Это необходимо, потому что объект может быть удален, пока умные указатели все еще находятся в std::set.

. Вы должны также использовать std::owner_less для набора shared_ptr с.

1 голос
/ 23 апреля 2020

Но когда я использую std :: vector >, мне разрешается откатываться назад и обратно. Но я хотел бы, чтобы функциональность, аналогичная std :: set.

std::set, была заказанным контейнером. Это означает, что когда вы вставляете что-то, структура данных нуждается в некоторых сравнениях, чтобы найти свое правильное место (внутри внутреннего дерева). Из-за этого, как упомянул @ j6t, вам нужно ввести оператор сравнения при определении набора. Это не относится к std::vector, потому что для std::vector вы сохраняете элементы один за другим, без каких-либо сравнений.

...