лязг против gcc: вариационные лямбда-захваты - PullRequest
11 голосов
/ 29 мая 2019

Я пытаюсь перехватить аргумент лямбда-вариации во внутренней лямбде и использовать его там.В качестве примера рассмотрим следующий код:

int main () {
    auto first = [&] (auto&&... one) {
        auto second = [&] (auto&&... two) {
            return ((one * two) + ...);
        };
        return second(one...);
    };
    return first(5);
}

Это работает с gcc9, но не работает с clang8 (https://godbolt.org/z/i2K9cK).

. Способ сделать код компиляцией - явно захватить [&one...],но мне было интересно, является ли это ошибкой в ​​clang.

Также интересно: изменение оператора return на что-то, где one напрямую раскрывается (перед объединением с two), это компилируется снова: return (((one * ...) * two) + ...);

Я нашел этот связанный пост, но объявленная там ошибка, кажется, исправлена ​​в clang8.

1 Ответ

1 голос
/ 02 июня 2019

Это ошибка в Clang.Было сообщено .За комментарий :

Исправлено в r362358.

(Примечание: у Clang, похоже, проблемы с расширениями пакетов в захватах в целом. Давайтеразверните нашу собственную версию типа замыкания, сгенерированного для универсальной лямбды first:

struct __closure_first {
    template <typename... Args>
    auto operator()(Args&&... one) const
    {
        auto second = [&] (auto&&... two) {
            return ((one * two) + ...);
        };
        return second(one...);
    }
};

Очевидно, что это не настоящий тип замыкания, и у незамкнутых локальных классов не может быть шаблонов функций-членов.это в глобальном масштабе, GCC по-прежнему работает и Clang по-прежнему не удается .)

...