В C ++ как умножить итератор вектора, который содержит элементы std :: variable? Делаете приведение типа итератора? - PullRequest
0 голосов
/ 12 января 2020
#include <iostream>
#include <vector>
#include <string>
#include <variant>

struct S1 { int a {}; };
struct S2 { std::string b {}; };
using Struct_variant = std::variant< S1, S2 >;

int main() {
    std::vector<Struct_variant> struct_vector { S1 {1}, S2 {"hello"}, S1 {3}};
    size_t index_to_erase {1};  // NOTE: assume we only know the index, *not* the iterator.
    auto variant_itr = struct_vector.begin();

    // following line requires either a std::vist, or an "if std::holds_alternative" to handle types.
    variant_itr =  struct_vector.begin() * index_to_erase;
    // for (int i = 0; i != index_to_erase; i++) variant_itr++;  // works
    struct_vector.erase(variant_itr);
    std::cout << struct_vector.size() << std::endl;
}

Я не до конца понимаю, почему приращение работает, а умножение - нет. Что такое static_cast <> ()?

Любая помощь приветствуется.

Ответы [ 2 ]

3 голосов
/ 12 января 2020

Умножение итератора или указателя не имеет определения или значения. «Точка в пространстве» не может быть «умножена» ни в программировании, ни в реальной жизни. Только расстояния / промежутки / количества могут быть умножены.

Похоже, вы просто с помощью sh продвинете итератор на index_to_erase пробелов. Это сложение .

const auto variant_itr = struct_vector.begin() + index_to_erase;

Вот и все!

Лог c для превращения этого в некоторый базовый шаг вперед по указателю index_to_erase*sizeof(Struct_variant) сделан для вас, если действительно, итератор для вашего контейнера так же прост, как указатель на данные.

Обратите внимание, что это работает только для итераторов с произвольным доступом; в более общем случае вы можете использовать std::advance или std::next, но если вам это понадобится, ваше решение, вероятно, неэффективно.

1 голос
/ 12 января 2020

Я не до конца понимаю, почему приращение работает, а умножение - нет.

Краткий ответ: для итераторов определен оператор приращения (++), умножения - нет t.

Длинный ответ

Операции над итератором не являются алгеброй, где позиция begin() имеет значение 1.

Итератор - это эволюция указателя, это число, представляющее позицию в памяти, и в первом приближении (также во втором приближении с std::vector s) вы можете рассуждать, считая итератор указателем.

Предположим, что begin() возвращает 1000 и что размер Struct_variant равен 10 (законченные выдуманные числа).

С помощью variant_itr++ вы увеличиваете значение указателя (итератора), что is (указатель арифмети c) вы получаете не 1001 (1000 плюс 1), а 1010, то есть позицию для следующего Struct_variant.

Если вы применяете приращение 5 раз (например), Вы получаете указатель в позиции 1050, а не 1005.

Учитывая этот тип арифметики c, совершенно не имеет смысла умножение.

И не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...