Я хотел бы иметь возможность использовать диапазоны C ++, чтобы упростить логику кода c с помощью архивирования контейнеров, а не явной индексации в них. Я могу заставить это работать с подробным лямбда-аргументом, но я бы скорее попытался сделать его более простым / обобщенным с большим количеством auto
.
const int n = ...;
std::vector<float> a(n), b(n), c(n);
...initialize a and b...
// This works
ranges::for_each(
ranges::views::zip(a, b, c),
[](const std::tuple<float&, float&, float&>& v)
{
const auto& [a, b, c] = v;
c = a + b;
std::cout << typeid(v).name(); // NSt3__15tupleIJRfS1_S1_EEE
}
);
// This fails
ranges::for_each(
ranges::views::zip(a, b, c),
[](const auto& v)
{
const auto& [a, b, c] = v;
// c = a + b;
std::cout << typeid(v).name(); // N6ranges12common_tupleIJRfS1_S1_EEE
}
);
В документации Ranges-v3 написано следующее:
views::zip
Если даны N диапазоны, вернуть новый диапазон, где Mth элемент является результатом вызова make_tuple
на элементах Mth всех диапазонов N .
Это заставляет меня думать, что я должен быть в состоянии преобразовать ranges::common_tuple
в std::tuple
, и я посмотрел на * publi c членов и нашел:
std::tuple< Ts... > const & base() const noexcept
Однако это также не компилируется:
const auto& [a, b, c] = v.base();
// error: no member named 'base' in 'std::__1::tuple<float, float, float>'
Но когда я печатаю typeid(v)
, это не std::tuple
; это ranges::common_tuple
. Возможно ли здесь то, что я пытаюсь сделать с auto
выводом типа? (лягушка компилятор, если это имеет значение)