2011-10-21 9 views
6

mam problem że kiedy używać coś takiego:Jak wrócić „nie znaleziono”, gdy wartość zwracana jest const odniesienia

const MyList& my_list = getListForThisRegion(/*region ID, ...*/); 

Nie wiem co wrócić, gdy wartość nie zostanie znaleziona.

Mój problem polega na tym, że chciałbym mieć sposób, aby zasygnalizować (podczas zwracania wartości z getListForThisRegion) "wartość nie znaleziono" dla osoby dzwoniącej. Jeśli zwróciłem wskaźnik, mógłbym zwrócić nullptr, ale nie wiem jak to zrobić z referencjami. Wszystko, co mogę wymyślić, to posiadanie statycznego elementu not_found typu MyList i zwrócenie do niego odwołania, ale wydaje się to brzydkie.

I tak, nie mogę zwrócić wartości, ponieważ listy są "grube" i często używane.

EDYCJA: tona wspaniałych odpowiedzi, ale wyjątek nie jest dopuszczalnym rozwiązaniem, ponieważ liczba razy byłaby podnoszona jest wysoka (odsetek: nbNotFound/nbCalls jest wysoki).
EDIT2: odnośnie doładowania :: opcjonalnie - jak skomplikowane jest opanowanie? Chodzi mi o to, że wymaga ona nieoczywistej wiedzy (nieoczywistość = coś, co nie jest po prostu znajomością składni)?

+3

Wyrzucanie wyjątku może być dobrym rozwiązaniem. – BigMike

+1

możesz również chcieć spojrzeć na 'boost :: optional' – Akanksh

+0

Odwołanie musi odnosić się do obiektu, więc możesz rzucić wyjątek lub nie używać odwołania. 'boost :: optional' to świetny wybór, ale może to być przesada; po prostu użyj wskaźnika. – GManNickG

Odpowiedz

7

Istnieją dwa sposoby obsługi idiomatyczne to:

  • zmienić interfejs, aby powrócić do typu, który ma zdolność do odnoszą się do niczego (na przykład wskaźnik, który może być null, iterator do end).

Albo

  • wyjątek, jeśli element nie zostanie znaleziony.

Zwracanie fikcyjny obiekt jest nieco hacky, a ty nic nie zyskać na powrocie wskaźnik jak trzeba jeszcze sprawdzić wynik przeciwko szczególnej wartości (null lub fikcyjnego obiektu).

+3

'boost :: optional' to dobry typ tutaj. –

+0

@ edA-qamort-ora-y: to zmieniłoby semantykę, aby powrócić przez wartość zamiast referencji (chyba że zwrócisz opcjonalne odwołanie, ale nie widzę, co to dodaje do wskaźnika). –

+0

@Mike: A propos 'boost :: optional >'? – fredoverflow

1

Zapisałbym klasę wyjątku (w razie potrzeby hierarchię) i wyrzucił wyjątek dla takiego przypadku.

1

Widzę tylko dwie możliwości: albo masz specjalnego członka w klasie MyList, który deklaruje, że instancja jest "null" (nie ustawiona), albo możesz rzucić wyjątek.

+1

Posiadanie członka w 'MyList' w celu wskazania wartości pustej wydaje się bardzo uciążliwe. Tego rodzaju cecha jest często lepsza dzięki owinięciu obiektu w inny. 'Boost.Optional ' zapewnia takie opakowanie do reprezentowania obiektu zerowego. –

1

Możesz śledzić numer std::map i wstawić domyślnie skonstruowaną listę do swojego kontenera, a następnie odesłać do niej odniesienie. Oczywiście zależy to od braku różnicy semantycznej między domyślną listą a listą, której wcale nie ma.

Można także dodać funkcję zapytania, która wyszukuje określony region, i zwraca wartość true, jeśli ma listę, a false w przeciwnym wypadku. Następnie możesz rzucić wyjątek w swoim akcesorium bezpiecznym ze świadomością, że nie będzie to częste zjawisko.

3

Co powiesz na przepisanie funkcji, aby odnieść się do "returnValue", w której umieścisz listę do zwrócenia? Wtedy funkcja może zwrócić wartość logiczną wskazującą znaleziony/nie znaleziony.

bool getListForThisRegion(/*region ID, ...*/, MyList& ret_list); 
Powiązane problemy