& quot; Неинициализированная захваченная ссылка & quot; ошибка при использовании лямбды в выражении фолд — 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:

((а, б), в)


При вызове и печати fold_left(cat, a, b, c, d) (более 3 аргументов), Clang ++ 5 выходов:

(((а, б), в), г)

Вместо этого 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?

12

Решение

Это ошибка gcc 47226. gcc просто не позволяет создавать пакетные расширения лямбд.

Тем не менее, у вас нет причин помещать лямбду в пакет расширения. Или даже использовать лямбду вообще:

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]