我正在尝试编写一个将函数映射到多个迭代器的函数。这就像是
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!
}
澄清备用解决方案然而,使用此功能意味着乐趣无法返回void
答案 0 :(得分: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
必须处理迭代器的所有值类型,并且范围必须相等。函数对象通过引用传递,您可以修改它以进行品味。
更新:如果我误解了您希望f
同时对所有值进行操作,那么您应该删除apply_helper
并调用f(begin, others...)
并且创建一个函数f
,它接受所有这些迭代器。