将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;
答案 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