为什么lambda表达式不需要<functional>,但函数<void()>呢?

Gst*_*tso 25 c++ lambda

我有一些代码使用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;
}
Run Code Online (Sandbox Code Playgroud)

这不需要 #include< functional>编译,但如果我使用变量来存储lambda函数:

#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;
}
Run Code Online (Sandbox Code Playgroud)

然后我需要包括<functional>编译,为什么?为什么sort()不包括<functional>呢?

Ben*_*ley 46

因为lambda表达式是编译器提供的核心语言特性.std::function是一个库函数,用代码实现.请注意,您不需要包含任何内容来将lambda存储在变量中.

auto f = [](int x, int y){ return x < y; };
Run Code Online (Sandbox Code Playgroud)

<functional>如果您打算将其存储在a中,则只需要包括std::function(因为它就是实现它的地方).

你似乎认为lambda的类型是a std::function.它不是.每个lambda表达式都有自己唯一的,不可命名的类型.我抓住了上面的那种类型auto.std::function是一种更通用的类型,可以使用适当的签名存储任何类似函数的对象.例如,我可以创建一个std::function<int(int,int)>对象,并为其分配一个普通函数,一个函数对象和一个lambda.

#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;
}
Run Code Online (Sandbox Code Playgroud)

以动态分配和间接的形式存在这种普遍性的成本.而通常使用lambda通过其实际类型的变量来内联.

  • @ user2296177"必须"对某些对象(函数指针和其他一些对象),"可能"对于对象(通常在一定大小下),但是没有任何要求必须在std中使用SOO存储小lambda: :function(这是一个库实现问题的质量).如果我没记错的话,一个流行的std库(MSVC)将SOO任何可调用的不大于两个`std :: string`s(它们本身就有短字符串的SOO). (2认同)

R S*_*ahu 6

lambda函数是语言的一部分 - 独立于任何库.

std::function另一方面,它是标准库的一部分,在标准库头文件中定义functional.

因此,使用

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

不需要functional#include同时使用ð

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

要求functional#included.