"Uninitialized captured reference" 在折叠表达式中使用 lambda 时出错 - clang 与 gcc
"Uninitialized captured reference" error when using lambdas in fold expression - 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
我的代码格式不正确吗出于某种原因,或者这是一个 g++7 错误?
这是gcc bug 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;
}
考虑以下代码:
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
我的代码格式不正确吗出于某种原因,或者这是一个 g++7 错误?
这是gcc bug 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;
}