Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undocumented GCC C++11 extension? Capturing arbitrary expressions in lambda capture lists

Strangely enough, GCC 4.7.2 seems to have no problem with the following code:

template<typename T>
T&& identity(T&& x1) {
    return std::forward<T>(x1);
}

int main(int, char**) {
    int x1 = 1;
    int &x2 = identity(x1);
    auto f = [&x1]() mutable {
        x1 = x1 + 1;
    };
    auto g1 = [y=x2+1]() {
        static_assert(std::is_same<decltype(y), const int>::value, "fail");
        std::cout << "g1: " << y << std::endl;
    };
    auto h1 = [y=identity(x1)+1]() {
        static_assert(std::is_same<decltype(y), const int>::value, "fail");
        std::cout << "h1: " << y << std::endl;
    };
    auto g2 = [&y=x2]() {
        static_assert(std::is_same<decltype(y), int&>::value, "fail");
        std::cout << "g2: " << y << std::endl;
    };
    auto h2 = [&y=identity(x1)]() {
        static_assert(std::is_same<decltype(y), int&>::value, "fail");
        std::cout << "h2: " << y << std::endl;
    };
    f(); g1(); h1(); g2(); h2();
    f(); g1(); h1(); g2(); h2();
    return 0;
}

The results are the following:

g1: 2
h1: 2
g2: 2
h2: 2
g1: 2
h1: 2
g2: 3
h2: 3

I can't seem to find any mention of capturing arbitrary expressions in lambda capture lists, even in n3285 (dated 2012-10-02). Also, I can't seem to find any documentation of this as an official GCC extension anywhere.

Is this an undocumented GCC extension (a la VLAs as structure members, a proposed/upcoming C++ feature that GCC has gone ahead and implemented early, neither, both, or what?

like image 536
Stephen Lin Avatar asked Apr 02 '13 03:04

Stephen Lin


1 Answers

As noted in the comments, the feature is broadly similar to a recent proposal but it was implemented long before initial standardization. GCC served as a prototype during the standard development and initially reflected whatever ideas the authors liked, which were later refined. Some ideas which had to be trimmed to keep the standard reasonably simple are getting reintroduced as proposals. Lambdas have a lot of room to grow.

For now, this is just another bug. It was never removed from the original implementation because nobody has reported it yet.


Update: This is now a standard feature since C++14.

like image 57
Potatoswatter Avatar answered Sep 23 '22 22:09

Potatoswatter