Set vs const.

0

Witam.

Mam następujący problem.
Załóżmy, że mam kontener set wewnątrz którego jest para, bądź krotka.

set<pair<double,double>> path;
set<pair<double,double>>::iterator it;

bądź (nazwa iteratora nie ma tutaj znaczenia bo każdy z tych setów jest z innego przykładu)

set<tuple<int,int,int,int>> visited;
set<tuple<int,int,int,int>>::iterator it; 

Jeśli chcę odczytać jakiś element z krotki robię to następująco

  get<1>(*it)

Natomiast gdy chcę zmienić to otrzymuje błąd, iż wartość ta jest typu const.

  get<1>(*it)=5

Jeżeli powyższe wyrażenie zastąpić konkretną nazwą.

tuple<int,int> nazwa;
nazwa=make_tuple(1,2);
get<0>(nazwa)=5;
 

To wszystko działa ok.

W jaki sposób zmienić tą wartość ? Dotychczas robiłem to usuwając stara i dodając nową.

Pozdrawiam

0

nie wiem jak działa tuple, ale wiem że set działa tak:

set<int> aaa;
aaa.insert(111);
aaa.insert(22);
aaa.insert(4446);
aaa.insert(777);
aaa.erase(111);
for (set<int>::iterator it = aaa.begin(); it!=aaa.end(); it++)
    printf("%d\n",*it);

dodatkowo zamiast set< pair<X,Y> > lepiej użyć: map<X,Y>

0

Elementów siedzących w kontenerze set nie można modyfikować. Można je co najwyżej usuwać/dodawać "w całości". Jeśli chcesz zmodyfikować jakąś krotkę to musisz ją najpierw usunąć z set, zmodyfikować i z powrotem wstawić.

Elementy w kontenerze set są połączone w drzewo o strukturze określonej przez kolejność elementów. Jeśli zmieniłaby się wartość elementu to zmieniłaby się też kolejność a struktura stałaby się błędna. Dlatego set::iterator zwraca tylko const-referencję:

set<int>::iterator it = ...

const int &X = *it; // OK
      int &Y = *it; // źle
0

Dziękuje za odpowiedź teraz już wiem. Korzystając z okazji może mi ktoś powiedzieć gdzie leży błąd ?

for (it=pierwsze.begin();it!=pierwsze.end();++it)
	{
		sum+=(*it);
		pierwsze.erase(it);   // <-  po dodaniu tej linijki wyskakuje błąd.
	}
 

Zdaje sobie sprawę, że istnieje metoda usunięcia wszystkich elementów seta bądź usunięcia rekordów z danego zakresu ale mnie chodzi o usunięcie wyrazu spełniającego konkretny warunek.
np.

if ( (*it)==3) pierwsze.erase(it);
 

Gdy tylko nie dzieje się to w pętli to mogę robić co chce tzn usuwać, inkrementować itp. Natomiast po dodaniu linijki z erase wyskakuje błąd.
"Debug asertion failed " " Expresion map/iterator not incrementable"
Daję ponów próbę, następnie break i kompilator odsyła mnie do tego wyrażenia.

for (it=pierwsze.begin();it!=pierwsze.end();++it) 

Sęk w tym, że bez frazy erase wszystko działa. Nawet dodawałem if'a sprawdzającego czy

it!=pierwsze.end(); 
0

Jak usuwasz element to iterator do niego przestaje być ważny. Najprościej jest przenieść zwiększenie iteratora do pierwsze.erase(it++); albo tworzyć jawnie jakieś iteratory tymczasowe.

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