unordered_map używa usuniętych konstruktorów kopiujących unique_ptr i pair

0

Cześć. Miałem zamiar napisać sobie taki "projekcik" na parę wieczorów, i prawie by mi się udało, gdyby nie te przeklęte bugi (;D)

Tutaj jest część, która psuje mi wszystko:

using drawable_unique = std::unique_ptr<buffer_drawable>;
using pos = std::pair<int, int>;
...
std::unordered_map<drawable_unique, pos> text_objs = {
        {std::make_unique<buff_text>(buff_text("Hey wassup")), std::make_pair(5,5)}
    };

A tutaj błędzik: https://pastebin.com/CULE4utT

Szukałem trochę, bawiłem się z obiektami lokalnymi i movami, ale wszystko przynosiło taki sam efekt. Trochę to dołuje, bo potrzebuję skończyć to w miarę szybko.
Prosiłbym o pomoc.

1

Klucz w map/set jest const. Nie trzymaj w nim danych, to nie będzie problemu.

0
kq napisał(a):

Klucz w map/set jest const. Nie trzymaj w nim danych, to nie będzie problemu.

Czyli użyć np. vector<pair<drawable_unique, pos>>?

3

Pytanie: czemu drawable_unique jest kluczem? Dlaczego nie map<buffer_drawable*, data>, gdzie data to struct data{ unique_ptr<buffer_drawable>; pos position; }?

Ogółem nie bardzo rozumiem całego zamysłu. unordered_x ma oferować lookup w amortyzowanym O(1), tylko jak ma to zrobić jak klucz jest unique?

0
kq napisał(a):

Pytanie: czemu drawable_unique jest kluczem? Dlaczego nie map<buffer_drawable*, data>, gdzie data to struct data{ unique_ptr<buffer_drawable>; pos position; }?

Dlaczego taka dziwna mapa?
drawable_unique jest kluczem, ponieważ chcę mniej więcej zrobić zależność buffer_drawable <-> position

2

I w jaki sposób chcesz uzyskać kopię unique pointera będącego kluczem do wyszukania jego pozycji?

0
kq napisał(a):

I w jaki sposób chcesz uzyskać kopię unique pointera będącego kluczem do wyszukania jego pozycji?

Nie chcę kopii. Chcę mieć po prostu kontener, który grupuje mi unique_ptr'y i pair'y. unordered_map wydawał mi się najlepszy

0

Zupełnie nie rozumiem tej najlepszości w tym przypadku. unordered pozwala na szybki lookup klucza, ale ty klucza nie masz. Właściwie dlaczego dodasz pozycji jako pola buffer_drawable?

Może opisz co chcesz zrobić, bo pachnie mi to problemem XY.

0
kq napisał(a):

Zupełnie nie rozumiem tej najlepszości w tym przypadku. unordered pozwala na szybki lookup klucza, ale ty klucza nie masz. Właściwie dlaczego dodasz pozycji jako pola buffer_drawable?

Może opisz co chcesz zrobić, bo pachnie mi to problemem XY.

Mam klasę abstrakcyjną buffer_drawable, z której dziedziczy parę innych typów, które można wyświetlać. Implementują one jedynie ::draw(cbuffer&, std::pair<int, int>&).
No i co chcę zrobić.. Przeiterować po kontenerze zawierającym wskaźnik do obiektów buffer_drawable i je powyświetlać na odpowiednich pozycjach.
Sugerujesz dodać std::pair<int, int> pos jako cześć buffer_drawable i używać go bezpośrednio w draw()?

5

Mapa, gdzie kluczem jest std::unique_ptr i to jeszcze z domyślnym porównaniem kluczy, jest jak łódź podwodna na pustyni.
kq dobrze ci pisze, że ten kontener nie ma sensu.

To jest klasyczny problem XY.
Dlatego radzę ci opisz czemu służy ci ta mapa, a dostaniesz radę jak to zrobić prawidłowo, bez tego U-boot'a na Saharze.

2

Jeśli pozycja pasuje do tej abstrakcji to tak. W przeciwnym wypadku wektor par/struktur z nazwanymi elementami (czytelność tuple/pair jest bardzo wątpliwa, także w przypadku pozycji, gdzie pewnie chciałbyś x i y, albo angle i length, albo coś jeszcze innego).

Użycie unordered_map sugeruje, że chcesz rozsądnie szybko odnosić się do losowych elementów po kluczu, co nie ma tutaj zastosowania. Iteracja ciągła po mapie prawdopodobnie będzie też minimalnie wolniejsza. Dodatkowo klucz w map/set jest const, co może powodować problemy jeśli o tym nie wiedziałeś.

0
kq napisał(a):

Jeśli pozycja pasuje do tej abstrakcji to tak. W przeciwnym wypadku wektor par/struktur z nazwanymi elementami (czytelność tuple/pair jest bardzo wątpliwa, także w przypadku pozycji, gdzie pewnie chciałbyś x i y, albo angle i length, albo coś jeszcze innego).

Użycie unordered_map sugeruje, że chcesz rozsądnie szybko odnosić się do losowych elementów po kluczu, co nie ma tutaj zastosowania. Iteracja ciągła po mapie prawdopodobnie będzie też minimalnie wolniejsza.

Jeżeli pozycja pasuje do tej abstrakcji
można rozwinąć?

0

To akurat trochę kwestia gustu i jest mocno zależne od struktury programu. Zadaj sobie pytanie: czy posiadanie pozycji (i to w koordynatach konkretnego typu) jest podstawową cechą twojego bufora? Czy zawsze możesz się po nim tego spodziewać? Jeśli tak, to może mieć to sens. W przeciwnym wypadku może faktycznie lepiej trzymać te dane na zewnątrz. Ty znasz ten program najlepiej, wiesz w jakim kierunku będzie się rozwijał i jakie będzie jego przeznaczenie, nie ma tu jednoznacznej odpowiedzi.

0

Walczyłem trochę wczoraj, trochę dzisiaj, trochę szukałem, trochę grzebałem w kodzie i wyszło. Jednak ciekawi mnie jedna rzecz.

 std::vector<std::unique_ptr<drawable_unique>> text_objs;
    text_objs.emplace_back(std::make_unique<buff_text>(buff_text("hey", {5, 5})));
    

Ten kod generuje mi tą piękniutką ścianę tekstu: https://pastebin.com/KLYnZ3uu
Jednak gdybym zamiast emplace/push backowania std::make_unique<T>(...) dam new T(...), to wszystko chodzi ładnie.
Chodzi o usunięty copy c-tor, czy o co?

0

push_back z make_unique powinno śmigać. emplace_back przyjmuje parametry konstruktora, więc też powinno śmigać. Pokaż kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1