nnolte
nnolte

Reputation: 1780

clang vs gcc: variadic lambda captures

I am trying to capture a variadic lambda argument inside a inner lambda and use it there. As an example, consider this code:

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

This works with gcc9 but fails with clang8 (https://godbolt.org/z/i2K9cK).

A way to make the code compile is to explicitly capture [&one...], but i was wondering whether this is a bug in clang.

Also interesting: Changing the return statement to something where one is directly expanded (before combining with two), this compiles again: return (((one * ...) * two) + ...);

I have found this related post, but the bug declared there seems to be fixed in clang8.

Upvotes: 11

Views: 401

Answers (1)

L. F.
L. F.

Reputation: 20579

This is a bug in Clang. It has been reported. Per comment:

Fixed in r362358.

(Side note: Clang seems to have difficulty with pack-expansions in captures in general. Let's roll out our own version of the closure type generated for the generic lambda first:

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

Clearly, this is not a real closure type, and non-closure local classes cannot have member function templates. Putting this in the global scope, GCC still works and Clang still fails.)

Upvotes: 1

Related Questions