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

Почему для лямбда-выражений не требуется <functional>, но функция <void()> делает?

У меня есть выражение для lambda, использующее код, например:

#include <vector>
#include <algorithm>
int main(){
    std::vector<int> vi={3,1};
    std::sort(vi.begin(),vi.end(),[](int x,int y){
        return x<y;
    });
    return 0;
}

Для компиляции не требуется #include< functional>, но если я использую переменную для хранения лямбда-функции:

#include <vector>
#include <algorithm>
#include <functional>
int main(){
    std::vector<int> vi={3,1};
    std::function<void()> compf=[](int x,int y){
        return x<y;
    };
    std::sort(vi.begin(),vi.end(),compf);
    return 0;
}

Затем мне нужно включить <functional> для компиляции, почему? И почему sort() уже не включает <functional>?

4b9b3361

Ответ 1

Поскольку выражение лямбда - это функция основного языка, предоставляемая компилятором. std::function - это функция библиотеки, реализованная в коде. Обратите внимание, что вам не нужно включать ничего для хранения лямбда в переменной.

auto f = [](int x, int y){ return x < y; };

Вам нужно включить <functional>, если вы планируете сохранить его в std::function (потому что там, где он был реализован).

У вас, похоже, создается впечатление, что тип лямбда - это std::function. Это не. Каждое выражение лямбда имеет свой уникальный, неподдающийся виду тип. Я взял этот тип выше, с auto. std::function - более общий тип, который может хранить любой объект, подобный функции, с соответствующей сигнатурой. Например, я могу создать объект std::function<int(int,int)> и назначить ему нормальную функцию, объект функции и лямбда.

#include <functional>
int minus_func(int a, int b) { return a - b; }

struct plus_t {
    int operator()(int a, int b) const { return a + b; }
};

int main() {
    auto mult_lambda = [](int a, int b) { return a * b; };

    std::function<int(int,int)> func;
    func = minus_func;
    func = plus_t{};
    func = mult_lambda;
}

Там также есть стоимость этой общности, в виде динамического распределения и косвенности. В то время как использование лямбда через переменную ее фактического типа очень часто встраивается.

Ответ 2

лямбда-функции являются частью языка - независимо от каких-либо библиотек.

std::function, с другой стороны, является частью стандартной библиотеки и определяется в файле заголовка стандартной библиотеки functional.

Следовательно, использование

std::sort(vi.begin(),vi.end(),[](int x,int y){
    return x<y;
});

не требует functional быть #include d при использовании

std::function<void()> compf=[](int x,int y){
    return x<y;
};
std::sort(vi.begin(),vi.end(),compf);

требуется functional быть #include d.