要使c ++ STL算法(例如for_each使用更多参数),重载在这里工作:
template<typename II1, typename II2, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++ ); }
return f;
}
template<typename II1, typename II2, typename II3, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, II3 _ii3, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++, *_ii3++ ); }
return f;
}
template<typename II1, typename II2, typename II3, typename II4, typename F>
F for_each( II1 _ii1, II1 ii1_, II2 _ii2, II3 _ii3, II4 _ii4, F f )
{
while ( _ii1 != ii1_ )
{ f( *_ii1++, *_ii2++, *_ii3++, *_ii4++ ); }
return f;
}
但有没有办法使用可变参数模板实现这种函数?
我只能以这种方式工作
void increase(){}
template< typename II1, typename ... IIn >
void increase( II1& _ii1, IIn& ... _iin )
{
++_ii1;
increase( _iin... );
}
template<typename F, typename II1, typename ... IIn >
F for_each( F f, II1 _ii1, II1 ii1_, IIn ... _iin )
{
while ( _ii1 != ii1_ )
{
f( *_ii1, *_iin ... );
increase( _ii1, _iin... );
}
return f;
}
#include <iostream>
int main()
{
int A[10];
int B[10];
int i = 0;
for_each( [&i]( int & v ) { v = i++; }, A, A+10 );
for_each( []( int a, int & b ) { b = a; }, A, A+10, B );
for ( int i = 0; i != 10; ++i )
{ std::cout << A[i] << "\t" << B[i] << "\n"; }
return 0;
}
非常难看。
编辑:(星期五6月22日21:12:28 CEST 2012)
要使用它,我必须编写如下代码:
for_each( function, begin1, end1, begin2, begin3 );
而stl的方式更受欢迎:
for_each( begin1, end1, begin2, begin3, function );
编辑:(星期五6月22日23:55:27 CEST 2012)
在@Hurkyl的帮助下,现在我有了这些代码:
namespace for_each_impl_private
{
template< typename F, typename InputIterator1, typename ... InputIteratorn >
F _for_each( F f, InputIterator1 begin1, InputIterator1 end1, InputIteratorn ... beginn )
{
while ( begin1 != end1 )
f( *begin1++, *beginn++... );
return f;
}
struct dummy {};
template< typename S, typename ... T >
void rotate_then_impl( S s, T ... t )
{
rotate_then_impl( t..., s );
}
template< typename S, typename ... T>
void rotate_then_impl( S s, dummy, T ... t )
{
_for_each( s, t... );
}
}//namespace for_each_impl_private
template< typename ... T >
void for_each( T ... t )
{
static_assert( sizeof ... ( t ) > 2, "for_each requires at least 3 arguments" );
for_each_impl_private::rotate_then_impl( t..., for_each_impl_private::dummy() );
}
#include <iostream>
int main()
{
int A[10];
int B[10];
int i = 0;
for_each( A, A + 10, [&i]( int & v ) { v = i++; } );
for_each( A, A + 10, B, []( int a, int & b ) { b = a; } );
for_each( A, A + 10, B, []( int a, int b ) { std::cout << a << "\t" << b << "\n"; } );
return 0;
}
答案 0 :(得分:3)
你可以扩展不是参数本身,而是扩展表达式,就像你在这里做的那样
*_iin ...
这意味着
来自_iin_k
的每个_iin
的执行解除引用并将操作结果放入函数
但是你可以在这里使用每个表达式,所以你可以写
*_iin++...
答案 1 :(得分:1)
我没有编译器方便测试这个,但你应该可以做类似以下的事情:
class dummy {};
template< typename S, typename T...>
void inner_func(S s, T... t);
template< typename S, typename T...>
void rotate(S s, T... t)
{
rotate(t..., s);
}
template< typename S, typename T...>
void rotate(S s, dummy, T... t)
{
inner_func(s, t...);
}
template< typename T...>
void outer_func(T... t)
{
rotate(t..., dummy());
}
基本上,你可以通过反复向左旋转来将参数旋转到右边一个位置。 但是,您应该做其他事情。例如,
auto i = zip(i1_start, i2, i3, i4, i5);
for_each(i, i.end(i1_end), unzipper(function));
这可以让您使用普通for_each
,并且可以将zip
和unzipper
用于其他目的。可能更好,写一些让你这样做的东西:
for(auto &x : zip_view(i1_start, i1_end, i2, i3, i4, i5) {
unzip(function, x);
}