任意数量的块中的lambda函数的c ++可伸缩分组 [英] c++ scalable grouping of lambda functions in blocks of an arbitrary number

查看:59
本文介绍了任意数量的块中的lambda函数的c ++可伸缩分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须执行几个lambda函数,但是每个 N lambda都必须有一个 prologue()函数跑。 Lambda的数量可以任意大,并且在编译时已知 N 。这样的事情:

I have to execute several lambda functions, but every each N lambdas a prologue() function also must be run. The number of lambdas can be arbitrary large and N is known at compile time. Something like this:

static void prologue( void )
{
    cout << "Prologue" << endl;
}

int main()
{
    run<3>( // N = 3
        [](){ cout << "Simple lambda func 1" << endl; },
        [](){ cout << "Simple lambda func 2" << endl; },
        [](){ cout << "Simple lambda func 3" << endl; },
        [](){ cout << "Simple lambda func 4" << endl; },
        [](){ cout << "Simple lambda func 5" << endl; },
        [](){ cout << "Simple lambda func 6" << endl; },
        [](){ cout << "Simple lambda func 7" << endl; }
    );
}

输出:

Prologue
Simple lambda func 1
Simple lambda func 2
Simple lambda func 3
Prologue
Simple lambda func 4
Simple lambda func 5
Simple lambda func 6
Prologue
Simple lambda func 7
End

必须正确处理剩余物。

Remainders must be handled properly.

我已经达到了以下解决方案,但是正如您所看到的那样,它并不是具有很好的可扩展性,因为我必须为每个编写一个处理程序。 N

I have reached the following solution, but as you can see it is not very scalable because I have to write a handler for each N!

可以做一些魔术的元编程来覆盖所有可能的 N ?我是否失去了注意力,有完全不同的方法来解决此问题?一切都必须在编译时解决。

It is possible to do some magic meta-programming to cover every possible N? Have I lost the focus and there is a completely different approach to solve this problem? Everything must be resolved at compile time.

#include <iostream>    
using namespace std;

static void prologue( void );

// Primary template
template< int N, typename... Args>
struct Impl;

// Specialitzation for last cases
template< int N, typename... Args >
struct Impl
{
    static void wrapper( Args... funcs )
    {
        Impl<N-1, Args...>::wrapper( funcs... );
    }
};

// Specilitzation for final case
template<int N>
struct Impl<N>
{
    static void wrapper( )
    {
        cout << "End" << endl;
    }
};

template< typename Arg1, typename... Args >
struct Impl<1, Arg1, Args...>
{
    static void wrapper( Arg1 func1, Args... funcs )
    {
        prologue();
        func1();

        Impl<1, Args...>::wrapper( funcs... );
    }
};

template< typename Arg1, typename Arg2, typename... Args >
struct Impl<2, Arg1, Arg2, Args...>
{
    static void wrapper( Arg1 func1, Arg2 func2, Args... funcs )
    {
        prologue();
        func1();
        func2();

        Impl<2, Args...>::wrapper( funcs... );
    }
};

template< typename Arg1, typename Arg2, typename Arg3, typename... Args >
struct Impl<3, Arg1, Arg2, Arg3, Args...>
{
    static void wrapper( Arg1 func1, Arg2 func2, Arg3 func3, Args... funcs )
    {
        prologue();
        func1();
        func2();
        func3();

        Impl<3, Args...>::wrapper( funcs... );
    }
};

// Static class implementation wrapper
template< int N, typename... Args >
static void run( Args... funcs )
{
    Impl<N, Args...>::wrapper( funcs... );
}

编辑:发布了相关的问题

推荐答案

更简单的解决方案

template <std::size_t N, typename ... Ts>
void run (Ts const & ... fn)
 {
   using unused = int[];

   std::size_t  i { N-1U };

   (void)unused { 0, ( (++i % N ? 0 : (prologue(), 0)), (void)fn(), 0)... };
 }

-编辑-已添加(void)放在 fn()的调用前面,以避免Yakk在评论中解释逗号劫持的技巧(谢谢!)。

--EDIT-- added (void) in front to the call of fn() to avoid the comma-hijack trick explained by Yakk in a comment (thanks!).

这篇关于任意数量的块中的lambda函数的c ++可伸缩分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆