【问题标题】:How to capture variable number of arguments in lambda function如何在 lambda 函数中捕获可变数量的参数
【发布时间】:2013-05-13 17:18:10
【问题描述】:

我尝试了以下代码,但没有编译。

template <class T, class... A>
void tpool::enqueue(T&& func, A&&... args) {
    std::function<void()> task([func, args] () {
        //...
    });
}

【问题讨论】:

    标签: c++ templates c++11 lambda


    【解决方案1】:

    只需使用省略号。根据 C++11 标准的第 5.1.2/23 段:

    后跟省略号的捕获是包扩展 (14.5.3)。 [例子

    template<class... Args>
    void f(Args... args) {
        auto lm = [&, args...] { return g(args...); };
        lm();
    }
    

    结束示例 ]

    注意:有趣的是,GCC 拒绝编译这个(参见live example):

    template <class T, class... A>
    void foo(T&& func, A&&... args) {
        std::function<void()> task([func, args...] () {
            //...
        });
    }
    

    但考虑到上述标准中的示例,这绝对是编译器问题。

    【讨论】:

    • 太棒了,您是记住了整个标准还是只是快速浏览了一下?
    • 看起来像这个 gcc 错误:gcc.gnu.org/bugzilla/show_bug.cgi?id=41933(您的引用是对标准的较晚添加)
    • @MarcGlisse:哦,有趣。感谢您的信息!不确定这是否相关,但this 也无法编译...
    • 我认为这是同一个问题(捕获只是隐含的),但如果您有疑问,请随时在该错误报告中添加一个小测试用例(这也可能提醒人们该错误还在)。当你发现它们时,不要犹豫报告其他错误。
    • @MarcGlisse 仅供参考:两者都在 clang (llvm 3.2) 下编译查找。
    【解决方案2】:

    在捕获中使用args时,需要省略号:

    template <class T, class... A>
    void tpool::enqueue(T&& func, A&&... args) {
        std::function<void()> task([func, args...] () {
            //...
        });
    }
    

    【讨论】:

    • 我已经尝试过您的代码,但无法再次编译。我收到以下错误:error: expected ',' before '...' tokenerror: expected identifier before '...' tokenerror: parameter packs not expanded with '...'
    • @MarcoPacini 你在使用 GCC 吗?在这种情况下,编译器中似乎存在错误(如answer by Andy Prowl)。
    • 是的,我使用的 GCC 4.7.2 与 macport 一起安装。
    • 与 G++ 4.8.4 相同的问题。 G++ 票似乎暗示计划在 4.9 时间范围内解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多