Присоединиться к переменному количеству диапазонов

Вопрос задан: 8 месяцев назад Последняя активность: 8 месяцев назад
up 3 down

Мне нужно объединить несколько экземпляров boost::iterator_range. Моей первоначальной идеей было использовать boost::join, но похоже, что он принимает только два диапазона в качестве параметров. На другой вопрос я обнаружил, что наиболее проголосовавшим ответом было «ну, просто позвоните снова», но в моем случае это не работает. Я понял, что причина может заключаться в том, что я не знаю во время компиляции точное число диапазонов, к которым я собираюсь присоединиться, в результате чего boost::join не зная его тип возврата. Чтобы сделать это более понятным, мне нужно использовать его в цикле for, например:

SomeRangeType result;

for ( const auto& a_range : some_list_of_ranges )
{
    result = boost::join( result, a_range );
}

return result;

Существует ли другая операция соединения, подобная той, которая мне нужна? boost?

2 ответа

up 2 down

диапазон-v3 имеет concat а также join представления, кажется, вы хотите присоединиться к представлению здесь:

std::vector<std::vector<int>> v{{1, 2, 3}, {4}, {5, 6}};

for (auto e : v | ranges::view::join) {
    std::cout << e << " "; // 1 2 3 4 5 6
}

демонстрация

up 1 down

C++ не имеет динамических шаблонов во время выполнения, поэтому идея не работает с boost::range.

У нас может быть 2 диапазона r1 а также r2 с типами R1 а также R2 и когда мы join те, то мы получаем результат (давайте назовем его r12) типа boost::joined_range<R1,R2>.

Мы можем иметь третий диапазон (скажем, r3 типа R3) а также joinс этим r12 мы бы получили результат типа boost::joined_range<boost::joined_range<R1,R2>,R3>.

Диапазоны r1, r2, r3 и т. д. могут быть переданы в функцию шаблонов переменных в качестве аргументов, и из списка аргументов мы можем составить компилятор, чтобы выяснить, какой тип будет получен. То же самое, когда у нас есть диапазоны в коллекции фиксированной длины (например, std::tuple или же std::array), мы можем сделать компилятор, чтобы выяснить, какой тип соединения будет получен.

Однако, если у нас нет фиксированного количества диапазонов, но динамического количества во время выполнения (например, из std::vector) тогда мы не знаем, какой будет тип объединения, а также компилятор не может понять это во время компиляции. Однако каждый тип должен быть известен во время компиляции в C++.

Таким образом, вам нужно либо найти способ исправить количество диапазонов, к которым вы присоединяетесь во время компиляции, либо использовать эту динамическую несвязанную коллекцию (например, vector) диапазонов в качестве типа данных, или вы должны использовать какую-то третью вещь, например range-v3.