2011-06-14 90 views
2

我试图编写一个函数,它可以将函数映射到多个迭代器上。它会像C++ 0x:在多个迭代器上应用函数

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_over_variadic_args的函数fun需要被模板化,这意味着它不能是lambda,不能这需要污染全局命名空间的本地函数对象。

有人知道更好的解决方案吗?
谢谢

编辑:请注意,我希望尽可能的最大速度,因此解决方案保留内联所有函数调用的可能性将是首选。

Edit2:刚刚意识到我可以使用匿名命名空间将函数Fun的范围限制为一个文件。如果存在的话,我仍然很想知道一个更好的解决方案。

替代解决方案我发现只要将结果传递给另一个函数,我就可以将函数fun应用于可变参数包。所以,如果我有一个函数fun,我想申请到每一个说法,我可以这样做

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

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

澄清了替代的解决方案使用此然而意味着乐趣不能返回void

+0

你能举一个例子说明你会如何使用这个,或者甚至更好地说出你想要达到的目标? – 2011-06-14 19:56:49

+0

@Kerrek SB:fun_over_variadic_args的具体解决方案将在map_over_iterators中使用。一般来说,它可以在任何需要将函数应用于指定为可变参数的多个值的地方使用。 – Opt 2011-06-14 20:02:20

+0

@Sid:你介意制作一个能够显示这个对象的实际使用的最小例子吗? – 2011-06-14 20:06:11

回答

1

好吧,给你的问题的附加说明,或许还有可变参数这样就可以了:

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必须对所有价值型合作迭代器的s,并且范围必须相等。函数对象是通过引用传递的,你可以修改它来品尝。

更新:如果我误解,你想f对所有值同时工作,那么你应该摆脱apply_helper并调用f(begin, others...),使功能f这需要所有这些迭代器。