2015-08-10 3 views
0
vector<vector<string> > vvs; 
    vector<string> vs; 

    vs.push_back("r1-c1"); 
    vs.push_back("r1-c2"); 
    vs.push_back("r1-c3"); 

    vvs.push_back(vs); 

    for (vector<vector<string> >::iterator vvsi = vvs.begin(); vvsi != vvs.end(); vvsi++) { 
     vector<string> vec_str = *vvsi; 
     for (vector<string>::iterator vsi = vec_str.begin(); vsi != vec_str.end(); vsi++) { 
      cout << *vsi << ", "; 
     } 
     cout << "\n"; 
    } 

В приведенном выше C++ кода, чтобы избежать копирования вектора (вектор vec_str = * vvsi) я попытался код нижеC++ Программирование: Ошибка при назначении итератор вектора

vector<string> *vec_str = vvsi.base(); //Working. which (returns a const pointer&)  
vector<string> *vec_str = &(*vvsi); //Working. Assigning the address 

Но

vector<string> *vec_str = vvsi; //Error. Not able to assign 

Ошибка

(build error : cannot convert 'std::vector<std::vector<std::basic_string<char> > >::iterator to 'std::vector<std::basic_string<char> >*' in initialization) 

В случае intege г

int a=10; 
    int *b = &a; //working. Assigning address 
    int *c = &(*b); //working. Assigning address 
    int *d = b; //working. Assigning address 
    *c=11; 
    std::cout << a<<"\n"; 
    *d=12; 
    std::cout << a<<"\n"; 

В случае вектора, почему ошибка сборки при назначении (не в состоянии понять из итератора документации C++)?

ответ

3

Итератор не является указателем. Это интерфейс был использован как указатель, но он, конечно, не является указателем.

Однако, если вы просто хотите перебрать элементы каждого вектора в родительском векторе, нет необходимости назначить его временный вектор или указатель, сам итератор достаточно хорош:

for (vector<vector<string> >::iterator vvsi = vvs.begin(); vvsi != vvs.end(); ++vvsi) { 
    for (vector<string>::iterator vsi = vvsi->begin(); vsi != vvsi->end(); ++vsi) { 
     cout << *vsi << ", "; 
    } 
    cout << "\n"; 
} 

Кроме того, так как вы кладете C++ 11 в качестве тега в вашем вопросе, я полагаю, вы могли бы быть заинтересованы в более современном выражении:

for(auto& vst : vvs){ 
    for(auto& st : vst){ 
     cout << st << ", "; 
    } 
    cout << endl; 
} 
1

вы пытаетесь присвоить значение итератора для указатель. То, что итератор указывает на тот же тип, что и указатель, не имеет значения, поскольку RandomAccessIterators, которые являются типом итератора std::vector, неявно конвертируются в указатели.

Если вы используете C++ 11, существуют более простые способы повторения итерации вектора вектора, даже если это решение @A Hernandez (или любой контейнер контейнеров), используя синтаксис range-for доступны в C++ 14:

for(auto &&stringVec : vvs){ 
    for(auto &&str : stringVec){ 
     cout << str << ", "; 
    } 
} 
cout << '\n'; 

&& здесь позволяет связывание временных контейнеров, а также существующих, так что вы можете использовать этот синтаксис с обеих существующих контейнерных контейнеров и контейнерных контейнеров, возвращаемых из функции без сохранения их.

Смежные вопросы