2011-07-25 15 views
16

Definiując funkcję w interfejsie:Konst wektor const obiektów

virtual void ModifyPreComputedCoeffs (std::vector <IndexCoeffPair_t> & model_) = 0; 

chcemy określić, że model_ wektor nie powinny być zmieniane w tym sensie, operacje push_back etc nie powinny być wykonywane na wektorze , ale obiekty struktury IndexCoeffPair_t w modelu_ mogą zostać zmienione. Jak to określić?

virtual void ModifyPreComputedCoeffs (const std::vector <IndexCoeffPair_t> & model_) = 0; 

nie działa, jak sądzę.

+0

Cóż, co próbowaliście? –

+1

Nie działa, myślisz? Wygląda na to, że powinien działać, czy próbowałeś go zmodyfikować? – yan

+1

@yan: Nie, to nie powinno działać, ponieważ 'wektor :: operator [] const' i wszystkie inne elementy' const' zwracają element 'vector :: const_reference'. – Josh

Odpowiedz

7

Koncepcja dokładności C++ jest IMO przereklamowana. To, co właśnie odkryłeś, jest jednym z największych ograniczeń: nie skaluje się według kompozycji. Aby móc utworzyć wektor const obiektów niestanowiących stałych, należy zaimplementować własny typ wektora. Zwróćmy uwagę, że nawet biblioteka standardowa musiała wprowadzić nowe typy dla const_iterators.

Moja sugestia polega na używaniu poprawności const, gdzie jesteś zmuszony i nie wszędzie, gdzie możesz. Teoretycznie poprawność poprawności powinna pomóc programistom, ale wiąże się z bardzo wysokimi kosztami ze względu na składnię i jest bardzo prymitywna (tylko jeden bit, nie skaluje się według składu, wymaga nawet duplikacji kodu).

Również z mojego doświadczenia wynika, że ​​ta domniemana duża pomoc nie jest tak duża ... większość błędów, które łapie, jest związana z samą maszynerią poprawności, a nie z programową logiką.

Czy zastanawiałeś się kiedyś, dlaczego większość języków (w tym zaprojektowane po C++) nie wdrożyło tego pomysłu?

+9

const poprawność, niezależnie od opinii, istnieje w języku C++ i jest ważną cechą, która, jeśli uniknie się, może spowodować poważne bóle głowy i utratę czasu i pieniędzy w kodzie produkcyjnym. Chociaż podoba mi się ten sentyment (i niekoniecznie się nie zgadzam), jest to raczej komentarz do pierwotnego pytania niż odpowiedź. 6502 - zrobiłeś podobny argument przeciwko odpowiedzi const_iterator od Marka Ransoma. – Kit10

+1

@Copperpot: Tak, stała poprawność istnieje w C++ i jesteś zmuszony do radzenia sobie z tym, lubisz to lub nie. Jest to jeden z przypadków, w których rzekoma filozofia "płacenia za to, co chcesz" nie ma zastosowania, ponieważ musisz za to zapłacić, nawet jeśli nie chcesz tego. Z mojego doświadczenia z C++ nie pamiętam ani jednego przypadku (nawet JEDNEGO), w którym błąd poprawności stałej uniemożliwiał mi popełnienie prawdziwego błędu. Za każdym razem, gdy problem był w błędnych deklaracjach const (najczęstszym przypadkiem w moim doświadczeniu są to, co powinno być metodami const, które nie są zadeklarowane jako const). – 6502

+0

Ale absolutnie nie ma sensu, aby mieć wektor const niestanowiących elemetów i nie móc ich modyfikować (zachowuje się jak stały wektor elementów const). – Nuclear

12

Zamiast przekazywać wektor do funkcji, rób to, co robi biblioteka standardowa i przeprowadź parę iteratorów.

virtual void ModifyPreComputedCoeffs (std::vector <IndexCoeffPair_t>::iterator & model_begin, std::vector <IndexCoeffPair_t>::iterator & model_end) 
+2

Odsuwasz pytanie. Co jeśli musi on przekazać wektor takich wektorów? – 6502

+0

@ 6502, wydaje się to trochę poza zakresem pierwotnego pytania, nie sądzisz? –

+0

Niezupełnie.Zapytał, jak określić taki wektor i zasugerowałeś, że nie powinien on przekazywać wektora, ale dwa iteratory. Chociaż może to działać w tym konkretnym przypadku z niewielkim rozdrażnieniem (dwa parametry zamiast jednego), nie skaluje i nie odpowiada na pierwotne pytanie (jak określić ten wektor). Niestety odpowiedź w C++ brzmi "nie możesz, musisz zdefiniować własną klasę wektorów, aby to zrobić". – 6502

0

Jeśli jesteś w stanie zmodyfikować IndexCoeffPair_t, możesz dodać pewne funkcje składowe const i używać ich do zmiany niektórych członków, zmieniając członków w zmienne słowo kluczowe. Jest to jednak rodzaj hackowania, ponieważ teraz możesz zmienić zawartość dowolnego const IndexCoeffPair_t.

przykład:

class IndexCoeffPair_t { 
public: 
    void changeX(int newVal) const { 
     x = newVal; 
    } 

private: 
    mutable int x; 
}; 
+0

Coś w tym stylu całkowicie pokonało cel słowa kluczowego "const". Po co zawracać sobie głowę, jeśli coś oznaczającego "const" w ogóle nic nie znaczy ... :) – UncleBens

+0

Tak, ogólnie powinieneś unikać używania 'mutable', dlatego powiedziałem, że to hack. Jednakże, ponieważ OP chce, aby wektor był const, ale nie obiektami zawartymi, rozwiązałoby to konkretny problem. – MahlerFive

+0

IMO, to jest większe zło. Jedną z rzeczy jest martwienie się o potencjalne przyszłe nadużycie (?) Pojedynczej funkcji (jak często nazywasz 'push_back'?), Inną rzeczą jest to, że wszyscy użytkownicy mogą modyfikować obserwowalny stan obiektu const. – UncleBens

1

Może to być 14 C++ jako std::dynarray.

Faktycznie, jeśli rozmiar jest ustalony podczas kompilacji, można użyć std::array. Ale prawdopodobnie jest bardziej przydatny w programach wbudowanych, buforach, macierzach itd., Ponieważ często nie znasz żądanego rozmiaru do czasu wykonania lub chcesz, aby był konfigurowalny.

+1

std :: dynarray brzmi interesująco, ale zgodnie z aktualną [cppreference.com strona na dynarray] (http://en.cppreference.com/w/cpp/container/dynarray), nie będzie w C++ 14: "Po zapoznaniu się z komentarzem do n3690, ten komponent biblioteczny został odrzucony z dokumentu roboczego C++ 14 w osobnej specyfikacji technicznej, który nie jest częścią projektu C++ 14 od n3797". – Alan

+0

To wydaje się coraz mniej prawdopodobne ... – xaxxon

Powiązane problemy