12

考虑以下代码:

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 错误

4

1 回答 1

10

这是gcc 错误 47226。gcc 根本不允许产生这样的 lambda 包扩展。

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

template <typename F, typename Z, typename... Xs>
auto fold_left(F&& f, Z acc, Xs&&... xs)
{
    ((acc = f(acc, xs)), ...);
    return acc;
}
于 2017-04-19T15:38:19.107 回答