C ++ 0x: применение функции на несколько итераторов
-
27-10-2019 - |
Вопрос
Я пытаюсь написать функцию, которая будет отображать функцию по нескольким итераторам. Это было бы что -то вроде
template <class Fun>
fun_over_variadic_args(Fun fun) { }
template <class Fun, class First, class Rest...>
fun_over_variadic_args(Fun fun, First& first, Rest&... rest) {
fun(first);
fun_over_variadic_args(fun, rest...);
}
namespace {
template <class T> struct thunk_inc {
decltype(T::operator++()) operator()(T& t) { return ++t; }
};
}
template <class Fun, class MainIterator, class RestOfIterators...>
std::tuple<MainIt&, RestOfIts&...> map_over_iterators(Fun fun, MainIt& it, MainIt& end, RestOfIts&... rest) {
const thunk_inc();
for (; it!=end; fun_over_variadic_args(thunk_inc, it, rest...)) {
// Do something
}
}
Тогда проблема возникает в том, что функция Fun Fun в fun_over_variadic_args должна быть шаблона, что означает, что она не может быть лямбда и не может быть локальным объектом функции, который влечет за собой загрязнение глобального пространства имен.
Кто -то знает лучшее решение об этом?
Спасибо
РЕДАКТИРОВАТЬ: Обратите внимание, что мне нужна максимальная скорость, поэтому решения, которые сохраняют возможность внедрения всех функциональных вызовов, были предпочтительны.
EDIT2: только что понял, что я могу использовать анонимные пространства имен, чтобы ограничить развлечение функции до одного файла. Я все равно хотел бы знать актуальное решение, хотя, если он существует.
Альтернативное решение Я обнаружил, что могу применить веселье функции к варидовой упаковке аргументов, пока я передам результат другой функции. Так что, если у меня есть удовольствие от функции, которое я хочу применить к каждому аргументу, я могу сделать что -то вроде
template <class... T>
void foo(T... t) { }
template <class... Arg>
void test(Arg... arg) {
foo(fun(arg)...); // Works!
fun(arg)...; // Doesn't work!
}
Разъяснение для альтернативного решения Использование этого, однако, означает, что веселье не может вернуть пустоту
Решение
Хорошо, учитывая ваше дополнительное описание проблемы, возможно, что -то переменное, подобное этому, подойдет:
template <typename ItHead, typename... ItTail>
void advance_iterators(ItHead & it, ItTail ...others)
{
++it;
advance_iterators(others...);
}
template <typename It>
void advance_iterators(ItHead & it)
{
++it;
}
template <typename Fun, typename ItMain, typename ...ItOthers>
apply_helper(Fun & f, ItMain it, ItOthers ...others)
{
f(*it);
apply_helper(f, others...);
}
template <typename Fun, typename ItMain, typename ...ItOthers>
apply_helper(Fun & f, ItMain it)
{
f(*it);
}
template <typename Fun, typename ItMain, typename ...ItOthers>
apply (Fun & f, ItMain begin, ItMain end, ItOthers ...others)
{
while (begin != end)
{
apply_helper(f, begin, others...);
advance_iterators(begin, others...);
}
}
Очевидные ограничения здесь заключаются в том, что Fun
должен работать над всеми типами стоимости итераторов, и что диапазоны должны быть равными. Функциональный объект передается ссылкой, вы можете изменить его на вкус.
Обновлять: Если я неправильно понял и вы хотите f
Для работы по всем значениям одновременно, вы должны избавиться от apply_helper
И просто позвоните f(begin, others...)
и сделать функцию f
Это берет все эти итераторы.