问题 在折叠表达式中使用lambdas时出现“未初始化捕获的引用”错误 - clang vs gcc


请考虑以下代码:

template <typename F, typename X0, typename X1, typename... Xs>
auto fold_left(F&& f, X0&& x0, X1&& x1, Xs&&... xs)
{
    auto acc = f(x0, x1);
    return ([&](auto y){ return acc = f(acc, y); }(xs), ...);
}

const std::string a{"a"}, b{"b"}, c{"c"}, d{"d"}, e{"e"};
const auto cat = [](auto x, auto y) { return "(" + x + ", " + y + ")"; };

调用和打印时 fold_left(cat, a, b, c),g ++ 7和clang ++ 5输出:

((a,b),c)


调用和打印时 fold_left(cat, a, b, c, d)  (超过3个参数),clang ++ 5输出:

(((A B C D)

相反,g ++ 7会产生一个奇怪的编译时错误 (缩短)

prog.cc: In instantiation of 'auto fold_left(F&&, X0&&, X1&&, Xs&& ...) [*...*]':
prog.cc:17:43:   required from here
prog.cc:8:13: error: member 'fold_left(F&&, X0&&, X1&&, Xs&& ...) [*...*]
    ::<lambda(auto:1)>::<acc capture>' is uninitialized reference
     return ([&](auto y){ return acc = f(acc, y); }(xs), ...);
             ^
prog.cc:8:13: error: member 'fold_left(F&&, X0&&, X1&&, Xs&& ...) [*...*]
    ::<lambda(auto:1)>::<f capture>' is uninitialized reference

wandbox上的实例


我的代码是不正确的 出于某种原因,或 这是一个g ++ 7错误


11165
2018-04-19 14:44


起源

您是否打算为每个参数创建唯一的lambda类型 xs? - W.F.
有多少不同的“包装在GCC扩展lambda”问题你打算问? :) - T.C.
@ T.C。尽可能多的听到我们的lambda包扩大需求。 :d - Griwes


答案:


这是 gcc bug 47226。 gcc根本不允许生成像这样的lambdas包扩展。

但是,没有理由将lambda放入包扩展中。甚至可以使用lambda:

template <typename F, typename Z, typename... Xs>
auto fold_left(F&& f, Z acc, Xs&&... xs)
{
    ((acc = f(acc, xs)), ...);
    return acc;
}

10
2018-04-19 15:38