开发者

C++0x: applying function over multiple iterators

I'm trying to write a function that would map a function over multiple iterators. It would be something like

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
    }
}

The problem arises then that the function Fun in fun_over_variadic_args needs to be templated which means it cannot be a lambda and cannot be a local function object which entails polluting the global namespace.

Does someone know a better solution to this?

Thanks

Edit: Note that I want the maximum speed possible so solutions that preserve the possibility of inlining all the function calls would be preferred.

Edit2: Just realized that I could use anonymous namespaces to limit the scope of function Fun to one file. I 开发者_JAVA技巧would still love to know a neater solution though if one exists.

Alternate solution I found that I can apply a function fun to a variadic argument pack as long as I pass the result to another function. So if I have a function fun which I want to apply to every argument, I can do something like

template <class... T>
void foo(T... t) { }

template <class... Arg>
void test(Arg... arg) {
  foo(fun(arg)...); // Works!
  fun(arg)...; // Doesn't work! 
}

Clarification for alternate solution Using this however means that fun cannot return void


Alright, given your additional description of the problem, perhaps something variadic like this will do:

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...);
  }
}

The obvious restrictions here are that Fun has to work on all the value-types of the iterators, and that the ranges have to be equal. The function object is passed by reference, you can modify that to taste.

Update: If I misunderstood and you want f to operate on all values simultaneously, then you should get rid of apply_helper and just call f(begin, others...) and make a function f that takes all those iterators.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜