问题描述
|
我正在尝试编写一个可以在多个迭代器上映射一个函数的函数。就像
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应用于可变参量包。因此,如果我想将函数乐趣应用到每个参数,则可以执行以下操作
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,ItMain it)
{
f(*it);
}
template <typename Fun,typename ...ItOthers>
apply (Fun & f,ItMain begin,ItMain end,ItOthers ...others)
{
while (begin != end)
{
apply_helper(f,begin,others...);
advance_iterators(begin,others...);
}
}
这里明显的限制是ѭ3必须在迭代器的所有值类型上起作用,并且范围必须相等。该函数对象是通过引用传递的,您可以对其进行修改以进行品尝。
更新:如果我误解了,并且您想让f
同时对所有值进行运算,那么您应该摆脱apply_helper
,而只需调用f(begin,others...)
并创建一个函数f
即可使用所有这些迭代器。