2013-08-29 22 views
8

zauważyłem, że QMap::operator[](const Key & key) ma te dwie overloads:Dlaczego QMap :: operator [] (const Key & key) zwraca wartość?

T & QMap::operator[](const Key & key) 
const T QMap::operator[](const Key & key) const 

Czy istnieje powód do powrotu przez wartość?

A ponieważ mamy semantyki ruch:

po powrocie przez wartość, powinny kiedykolwiek wrócimy przez wartość const?

Powodem dlaczego pytam jest to:

Wyobraź mamy:

class ExpensiveToCopy; 
{ 
public: 
    int someProperty() const; 
    ... 
} 

void f(const QMap<int, ExpensiveToCopy>& map) 
{ 
    int lala = map[4].someProperty(); // We need to copy the entire object 
             // just to look at someProperty(); 
} 
+1

Tylko * jeden * przeciążenie zwraca wartość, drugi zwraca referencję. –

+2

@ Joachim Tak, to jest to, czego nie rozumiem. Czy nie powinny one zwracać odwołania, jak na przykład std :: vector :: operator []? –

+1

@nurettin it * does * inhibituje semantykę ruchu. – juanchopanza

Odpowiedz

11

W przypadku const nie możemy dodać element na mapie const jeśli nie istnieje , więc obiekt lokalny zostanie zwrócony.

W przeciwnym wypadku w przypadku nie będącym numerem const zostanie utworzony element z określonym kluczem (jeśli jeszcze go nie ma) przed zwróceniem do niego odwołania.

+3

To jest dokładnie to. Właśnie miałem napisać tę samą odpowiedź. Zauważ, że 'std :: map' nie ma' const operatora [] ', i prawdopodobnie jest to dobre. Mniej mylące. – juanchopanza

+0

W szczególności: przypadek 'const' musi być w stanie zwrócić" domyślny "skonstruowany element bez wstawiania czegokolwiek na mapę w przypadku, gdy element z danym kluczem nie zostanie znaleziony na mapie. Więc nie może zwrócić referencji. – juanchopanza

+0

@juanchopanza Może zwrócić referencję do statycznej zmiennej lokalnej, dzięki czemu możliwe jest zwrócenie odwołania do stałej. Czy ktoś chce, to inna sprawa ... – Sjoerd

0

Myślę, że brak odniesienia const polega na zapewnieniu, że kod klienta nie może w żaden sposób modyfikować kodu map. wiesz, jeśli użyjesz const_cast<ExpensiveToCopy>map[4] lub w inny sposób, nadal możemy zmodyfikować map[4], ale ten map[4] nie jest odniesieniem do czwartego elementu z map.