2016-03-22 14 views
2

dün geçirdiği neredeyse bir bizim ise bu şeyi ayıklama ve ben dize endekslerine 2D matris uygulamaya çalışmıştır o zamandan beri ben sonra ... C++ vektörü, başvurularda yineleme yapmıyor mu?

it.C

düşünmeye

class CSqrMatrix(){ 
    .... 
    void insert(string str){ 
    bool b = map.insert(str,m_size).second; 
    if (b){ 
     m_size++; 
     vector<int> ve; 
     for (int i = 0; i < m_vect.size(); i++) 
      ve.push_back(m_default); 
     m_vect.push_back(ve); 
     for (auto v : m_vect) 
      v.push_back(m_default); 
    } 
    ... 
map<string,int> map; 
vector < vector<int> > m_vect; 
int m_default; 
int m_size; 
}; 

duramazsın Ben

m_vect[0][0] = 8; 

gibi bir öğe ulaşmaya çalıştığında bazı eklemeler, ben geçersiz yazma ve segfault ... ve 0 oldu m_vect[0].size() değerini var; Her şeyi denedim, nihayet

for (int i = 0; i < m_vect.size(); i++){ 
    m_vect[i].push_back(m_default); 

programı iyi çalıştı gibi normal birine her döngü için değişti ...

Yani bu demek, v bir referecne Inst olduğunu, yapar ama elemanın yeni bir kopyası mı?

Teşekkür

+1

Evet bu doğru. Bir referans istiyorsanız, 'i (auto & v: m_vect) 'yi deneyin. –

cevap

2

kodu:

{ 
    auto && __range = (m_vect); 
    for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) 
    { 
     auto v = *__begin;  // <-- new copy in each iteration 
     v.push_back(m_default); // add item to the copy 
           // the copy goes out of scope 
    } 
} 

Yani, evet v bir referecne Inst, fakat:

for (auto v : m_vect) 
    v.push_back(m_default); 

(C'ye bakınız ++ standart [stmt.ranged]) Aşağıdaki eşdeğerdir Her iterasyonda yeni bir kopya mı?

Ne istiyorsun geçerli: eşdeğerdir

for (auto& v : m_vect) 
    v.push_back(m_default); 

için:

{ 
    auto && __range = (m_vect); 
    for (auto __begin = __range.begin(), __end = __range.end(); __begin != __end; ++__begin) 
    { 
     auto& v = *__begin; // <-- new reference in each iteration 
     v.push_back(m_default); 
    } 
} 
2

Evet v gerçekten de bir kopyasıdır (... telefonda yazdım, kod yazım hataları olabilir). Sen böyle yapmak gerekir:

for (auto& v : m_vect){ 
    v.push_back(m_default); 
} 

Ve std::vector kopya kap için ve gerçekten pahalı bir işlemdir tüm öğeler için derin bir kopya olduğunu unutmayın. Hatta düzenleme olmadan vektörler (std::vector<std::vector<T>>) bir vektör geçmesine isterseniz ref tarafından geçmelidir Yani (const ile Düzenlemeyi istemiyorsanız): In

for(/*const*/ auto& v:vectors){ 
    //... 
} 
2
for (auto v : m_vect) 
    v.push_back(m_default); 

formun üstündeki aralık-döngü, m_vect'da saklanan öğelerin kopyalarını (v) kullanarak yinelemektedir. Eğer m_vect yılında referanslar öğelere doğrudan kullanılmak istenirse

, sen auto& kullanarak, bu konuda açık olmalıdır:

// v references items in m_vect 
for (auto& v : m_vect) { 
    v.push_back(m_default); 
} 

İlginç this StackOverflow answer on using C++11 range-for bulabilirsiniz.