C ++ превращает векторный итератор в индекс - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть вопрос. У меня есть вектор, который содержит кортежи:

vector<tuple<int, int> > my_vector

Допустим, я хочу превратить свой итератор цикла в индекс по любой причине:

// Example program
#include <vector>
#include <tuple>

using namespace std;

int main()
{        
    vector<tuple<int, int> > my_vector;
    my_vector.push_back(make_tuple(1, 1));
    my_vector.push_back(make_tuple(2, 2));
    my_vector.push_back(make_tuple(3, 3));

    for (auto iterator : my_vector)
    {
        size_t index = distance(my_vector.begin(), iterator);
    }       
}

Честно говоря, я не понимаю, что янужно изменить, чтобы запустить его. Похоже, проблема в том, что я использовал итератор в distance. Может быть, кто-нибудь может дать мне какой-нибудь совет.

Ответы [ 3 ]

2 голосов
/ 08 ноября 2019

петля for на основе диапазона

for (range_declaration : range_expression) 
    loop_statement

примерно эквивалентна этому коду:

for (auto begin = range_expression.begin(), end = range_expression.end(); 
     begin != end; ++begin)
{
    range_declaration = *begin;
    loop_statement
} 

Обратите внимание на оператор *. Итак, range_declaration не итератор, а элемент, на который он указывает.

Если вам нужен индекс, используйте простой цикл for:

for (std::size_t index = 0; index < my_vector.size(); ++index)
     loop_statement
1 голос
/ 08 ноября 2019

C ++ превращает векторный итератор в индекс

Вы можете сделать это так:

std::size_t index = std::distance(std::begin(my_vector), iterator);

Но прежде чем вы сможете получить индекс от итератора, вы сначаланужно иметь итератор. Пример итератора для вектора:

// iterator to i'th element
auto iterator = std::next(my_vector.begin(), i);

for (auto iterator : my_vector)

Простое присвоение имени переменному итератору не делает его итератором. Цикл на основе диапазона проходит над элементами контейнера. Элементами этого вектора являются кортежи, а не итераторы.

Канонический способ иметь индекс при итерации элементов вектора - использовать традиционный цикл индекса:

using my_vec_t = decltype(my_vector);
for (my_vec_t::size_type i = 0; i < my_vector.size(); i++)

Если вы действительно хотите иметь индекс в цикле диапазона, это возможно с помощью указателей:

auto* front = &my_vector.front();
for (auto& element : my_vector)
{
    auto index = std::distance(front, &element);
}  
0 голосов
/ 08 ноября 2019

В цикле на основе диапазона это значение контейнера назначается не итератор.

Так что либо используйте следующее для цикла

#include <iterator>

//...

for ( auto it = std::begin( my_vector); it != std::end( my_vector ); ++it )
{
    size_t index = std::distance( std::behin( my_vector ), it );
}

Или используйте обычный цикл for синдекс.

for ( std::vector<std::tuple<int, int>>::size_type i = 0; i != my_vector.size(); i++ )
{
    auto it = std::next( std::begin( myvector ), i );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...