Подтвердить что ты не робот

Недокументированное расширение GCC С++ 11? Захват произвольных выражений в списках захвата лямбда

Как ни странно, GCC 4.7.2, похоже, не имеет проблем со следующим кодом:

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;
}

Результаты следующие:

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

Кажется, я не могу найти упоминания о захвате произвольных выражений в списках захвата лямбда, даже в n3285 (датировано 2012-10-02). Кроме того, я не могу найти документацию об этом как официальном расширении GCC в любом месте.

Является ли это недокументированным расширением GCC (a la VLAs как членами структуры, предлагаемой/предстоящей функцией С++, которую GCC уже реализовал и реализовал раньше, ни то, ни другое, или что?

4b9b3361

Ответ 1

Как отмечается в комментариях, эта функция в целом похожа на недавнее предложение, но она была реализована задолго до первоначальной стандартизации. GCC служил прототипом во время стандартного развития и первоначально отражал любые идеи, которые понравились авторам, которые впоследствии были уточнены. Некоторые идеи, которые нужно было урезать, чтобы сохранить стандарт достаточно простыми, вновь вводятся в качестве предложений. У Lambdas есть много возможностей для роста.

На данный момент это еще одна ошибка. Он никогда не удалялся из первоначальной реализации, потому что никто еще не сообщил об этом.


Обновление: Теперь это стандартная функция с С++ 14.