2011-07-25 17 views
16

nesneleri ancak, modeldeki IndexCoeffPair_t yapı nesneleri değiştirilebilir. Bunu nasıl belirtmeliyiz? Çalışmıyor bence işe yaramıyor.Sabit vektör bir arayüzde bir işlev tanımlarken

+0

Peki, ne denediniz? –

+1

Çalışmıyor mu? Elbette işe yarayacak gibi görünüyor, değiştirmeyi denediniz mi? – yan

+1

@yan: Hayır, işe yaramaz çünkü 'vektör :: operator [] const' ve diğer tüm const'ler elementleri 'vektör :: const_reference' döndürüyor. – Josh

cevap

7

C++ const-doğruluk konsepti IMO yolunda abartılmıştır. Keşfettiğiniz şey, sahip olduğu en büyük sınırlamalardan biridir: kompozisyona göre ölçeklendirilmez. Kendi vektör türünü uygulamak için ihtiyacınız olan const olmayan nesnelerin bir const vektörünü oluşturabilmek. Örneğin, standart kitaplığın bile const_iterators için yeni türler tanıtmak zorunda olduğunu unutmayın.

Benim önerim, zorladığınız her yerde değil, zorlandığınız yapı doğruluğunu kullanmaktır. Teoride, const doğruluğu programcılara yardımcı olmalı, ancak sözdiziminden dolayı çok yüksek bir maliyete sahiptir ve çok ilkeldir (sadece bir bit, kompozisyona göre ölçeklenmez, hatta kod çoğaltması gerektirir).

Ayrıca deneyimlerimde bu büyük yardımın gerçekten de o kadar büyük olmadığı ... yakaladığı hataların çoğu yapının doğruluk makinelerinin kendisi ile ilgilidir ve mantığı programlamamaktadır.

Hiç çoğu dillerin (C++ sonra tasarlananlar dahil) neden bu fikri uygulamadığını merak ettiniz mi?

+9

fikirden bağımsız olarak const doğruluğu, C++ 'da mevcuttur ve kaçınılması halinde üretim kodunda zaman ve parada büyük baş ağrılarına ve kayıplara neden olabilecek önemli bir özelliktir. Duyguyu sevdiğim halde (ve kesinlikle katılmıyorum), orijinal soruya bir cevaptan daha çok bir yorum. 6502 - Mark Ransom'un const_iterator yanıtına benzer bir argüman yaptınız. – Kit10

+1

@Copperpot: Evet, const + + içinde const doğruluğu var ve siz onunla başa çıkmak zorundasınız. “İstediğin şeyi öde” felsefesi olduğu iddia edilen davalardan biri de, istemiyor olsanız bile bunun bedelini ödemek zorunda olduğunuz için geçerli değildir. C++ ile yaşadığım tecrübelerimde, tek bir davayı bile (tek bir) bile hatırlayamıyorum, bu durumda bir sabit doğruluk hatası beni gerçek bir hata yapmaktan alıkoydu. Sorun her zaman yanlış const bildirimlerinde bulundu (benim tecrübemde en sık rastlanan durum, const bildirilmemiş const yöntemleri olmalıdır). – 6502

+0

Ama kesinlikle bir anlam ifade etmiyor, const olmayan elemetlerin const vektörüne sahip olmalı ve onları değiştiremiyor (const elemanlarının const vektörü gibi davranıyor). – Nuclear

12

Vektörü işleve iletmekten ziyade, standart kitaplığın ne yaptığını yapın ve bunun yerine bir çift yineleyiciyi geçirin.

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

Soruyu başka tarafa yönlendiriyorsunuz. Ya bu vektörlerin bir vektörünü geçmesi gerekiyorsa? – 6502

+0

@ 6502, bu orijinal sorunun kapsamı dışında görünüyor, sence de öyle değil mi? –

+0

Gerçekten değil.Böyle bir vektörün nasıl belirtileceğini sordu ve bir vektörü değil iki tekrarlayıcıyı geçmemesini önerdi. Bu durum, yalnızca küçük bir rahatsızlık (bu, bir yerine iki parametre) ile çalışabilirken, orijinal soruya cevap vermiyor (bu vektör nasıl belirlenir). Ne yazık ki C++'daki cevap “yapamazsınız, bunu yapmak için kendi vektör sınıfınızı tanımlamanız gerekir”. – 6502

0

IndexCoeffPair_t'u değiştirebilirseniz, bazı const üye işlevleri ekleyebilir ve bunları üyeleri değiştirilebilen anahtar sözcüğünü kullanarak değiştirilebilen bazılarını değiştirmek için kullanabilirsiniz. Bu bir tür kesintidir, çünkü artık herhangi bir const IndexCoeffPair_t'un içeriğini değiştirebilecektiniz.

Örnek:

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

private: 
    mutable int x; 
}; 
+0

Böyle bir şey, 'const' anahtar sözcüğünün amacını tamamen ortadan kaldırır. Neden "const" olsaydı bile bir şey ifade etmezse rahatsız olur :) :) – UncleBens

+0

Evet, genelde 'mutable' kullanmaktan kaçınmalısın, bu yüzden bunun bir hack olduğunu söyledim. Bununla birlikte, OP, vektörün içerilmeyecek, ancak içerilen nesneler olmasını istemediğinden, bu belirli problemi çözecektir. – MahlerFive

+0

IMO, bu büyük kötülük. Bir şey, tek bir fonksiyonun olası yanlış kullanımının (?) Endişelenmesidir (ne sıklıkla "push_back" diye adlandırırsınız?). Başka bir şey, tüm kullanıcıların bir const nesnesinin gözlemlenebilir durumunu değiştirebilmesinin tamam olduğunu söyler. – UncleBens

1

Bu olması muhtemeldir C++ 14 std::dynarray olarak.

Aslında, derleme zamanında boyut sabitlendiyse, std::array'u kullanabilirsiniz. Ancak, gömülü programlama, arabellek, matris gibi şeyler için daha fazla kullanım, ancak çalışma zamanına kadar istediğiniz boyutu bilmediğiniz veya yapılandırılabilir olmasını istediğiniz sıklıkta.

+1

std :: dynarray kulağa ilginç geliyor, ancak şu anki [cynorference.com sayfasındaki dynarray] 'a göre (http://en.cppreference.com/w/cpp/container/dynarray), C++ içinde olmayacak 14: "Ulusal organ yorumlarını n3690'a gözden geçirdikten sonra, bu kütüphane bileşeni C++ 14 çalışma kağıdından ayrı bir Teknik Spesifikasyona dahil edildi. Bu kapsayıcı, n3797'deki taslak C++ 14'ün bir parçası değil." – Alan

+0

Daha az ve daha az olası görünüyor ... – xaxxon

İlgili konular