可以表达lambda表达式的“类型”吗?

时间:2010-10-05 20:04:33

标签: c++ stl lambda c++11

将lambda表达式视为可调用对象的“语法糖”,是否可以表达未命名的基础类型?

一个例子:

struct gt {
    bool operator() (int l, int r) {
        return l > r;
    }
} ;

现在,[](int l, int r) { return l > r; }是上述代码的优雅替代品(加上gt的可调用对象的必要创建),但有没有办法表达gt(类型)本身?

一个简单的用法:

std::set<int, gt> s1;  // A reversed-order std::set
// Is there a way to do the same using a lambda?
std::set<int, some-magic-here-maybe([](int l, int r) { return l > r; }) > s2;

4 个答案:

答案 0 :(得分:59)

不,你不能把它放进decltype,因为

  

lambda表达式不应出现在未评估的操作数

您可以执行以下操作

auto n = [](int l, int r) { return l > r; };
std::set<int, decltype(n)> s(n);

但这真的很难看。请注意,每个lambda表达式都会创建一个新的唯一类型。如果之后您在其他地方执行以下操作,则t的类型与s不同

auto n = [](int l, int r) { return l > r; };
std::set<int, decltype(n)> t(n);

您可以在此处使用std::function,但请注意,这会产生一点运行时成本,因为它需要间接调用lambda函数对象调用运算符。这里可能忽略不计,但如果你想以这种方式将函数对象传递给std::sort,可能会很重要。

std::set<int, function<bool(int, int)>> s([](int l, int r) { return l > r; });

与往常一样,首先是代码然后配置文件:)

答案 1 :(得分:1)

直接回答您的问题:否。

你需要使用可以从任何类型分配的东西,类似于具有明确定义类型的仿函数。一个例子是std :: function,如sbi的答案所示。但是,这不是lambda表达式的类型。

答案 2 :(得分:0)

你可以使用一个小类lambda_wrapper&lt;&gt;来以低成本包装lambda。它比std :: function快得多,因为没有虚函数调用和动态内存分配。 Wrapper通过推导lambda参数列表和返回类型来工作。

typeOf[scala.Int]

答案 3 :(得分:0)

至少在Microsoft Visual Studio中(我没有尝试过其他编译器),如果你没有捕获任何东西,那么这个类型似乎是一个常规的函数指针:

@XmlRootElement