C++ 为什么不';t lambda表达式要求<;功能性>;,但是功能<;void()>;做

C++ 为什么不';t lambda表达式要求<;功能性>;,但是功能<;void()>;做,c++,lambda,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; } #包括 #包括 int main(){ 向量vi={3,

我有一些使用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;
}
#包括
#包括
int main(){
向量vi={3,1};
排序(vi.begin(),vi.end(),[](int x,int y){

返回x,因为lambda表达式是编译器提供的一种核心语言功能。
std::function
是一种库功能,在代码中实现。请注意,在变量中存储lambda不需要包含任何内容

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

这种通用性也要付出代价,比如动态分配和间接寻址。而通过实际类型的变量使用lambda通常是内联的。

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

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

因此,使用

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

要求
functional
成为
#include
d.

您是否认为lambda是std::function?它不是;当您将它存储到
compf
时需要进行转换。因为lambda表达式是语言的一部分。
std::function
是标准库的一部分,因此需要一个标头包括。@PaulRooney,公平地说,
for(inti:{1,2,3})
也需要一个头include,尽管没有明确的标准库用法。@chris true。我总是觉得这有点奇怪。
std::function
实现可能有静态存储,以避免对小于某个大小的可调用项进行动态分配。这类似于小字符串优化。行“func=plus\u t{应该有效吗?它会创建一个类型为“plus_t”的匿名对象吗?你的意思是“并分配给它”而不是“并分配给”?@blackpen:是的,它就是这样做的。它使用统一的初始化语法。我也可以对某些对象使用更传统的
func=plus_t();
@user2296177“必须”的(函数指针和一些其他的),“可能”对对象(通常在一定大小下)有限制,但没有规定必须将小lambda与SOO一起存储在std::function中(这是库实现的质量问题)。一个流行的std库(MSVC)如果我没记错的话,任何可调用的SOO都不会超过两个
std::string
s(它们本身有SOO表示短字符串)。
#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;
}
std::sort(vi.begin(),vi.end(),[](int x,int y){
    return x<y;
});
std::function<void()> compf=[](int x,int y){
    return x<y;
};
std::sort(vi.begin(),vi.end(),compf);