【问题标题】:Compiler bug, or non standard code? - Variadic template capture in lambda编译器错误,或非标准代码? - lambda 中的可变参数模板捕获
【发布时间】:2013-09-23 03:32:10
【问题描述】:

我有以下 C++11 代码;

template<typename... T>
int g(T... t)
{
    return 0;
}

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

int main()
{
    f(2, 5, 7);
}

我相信它是有效的 C++11,根据;标准第5.1.2.23条;

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

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

—结束示例]

然而,虽然 Clang++ 编译得很好,但 G++ 提供了这个错误;

main.cpp: In function 'void f(Args ...)':
main.cpp:10:23: error: expected ',' before '...' token
     auto lm = [&, args...] { return g(args...); };
                   ^
main.cpp:10:23: error: expected identifier before '...' token
main.cpp:10:26: error: parameter packs not expanded with '...':
     auto lm = [&, args...] { return g(args...); };
                      ^
main.cpp:10:26: note:         'args'
main.cpp: In lambda function:
main.cpp:10:43: error: expansion pattern 'args' contains no argument packs
     auto lm = [&, args...] { return g(args...); };
                                       ^
main.cpp: In instantiation of 'struct f(Args ...) [with Args = {int, int, int}]::__lambda0':
main.cpp:10:49:   required from 'void f(Args ...) [with Args = {int, int, int}]'
main.cpp:16:14:   required from here
main.cpp:10:19: error: using invalid field 'f(Args ...)::__lambda0::__args'
     auto lm = [&, args...] { return g(args...); };
                   ^

所以我的问题很简单,这是 G++ 中的编译器错误吗?

【问题讨论】:

    标签: c++ c++11 lambda variadic-templates compiler-bug


    【解决方案1】:

    GCC 中似乎没有实现支持。反之亦然,您不能在包扩展中包含 lambda(为每个包参数生成一个 lambda)。看来这两个功能根本不能一起玩。

    如果你只是简单地使用[&amp;],那么会有一个更有用的错误信息:

    抱歉,未实现:在模板中使用了“type_pack_expansion”

    免责声明:我的 GCC 副本是在 7 月下旬构建的;我可能需要升级了。

    【讨论】:

    • 哦,可爱...我可以使用 std::function 获得相同的行为吗? - 还是我必须更改为 Clang?
    • @Skeen 您可以使用将参数对象包传递给std::bind,第一个bind 参数是自定义仿函数模板类型,模板参数是类型包。 std::bind( my_func&lt; Args ... &gt;(), args ... )。我认为它应该适用于 my_func 作为“原始”函数模板,可能不需要成熟的仿函数,因为 bind 会为您处理状态存储。要“通过引用捕获”,请改用std::ref( args ) ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2020-05-02
    • 2017-05-05
    相关资源
    最近更新 更多