【发布时间】:2012-07-22 15:31:49
【问题描述】:
我在玩 c++11 的功能特性。我觉得奇怪的一件事是 lambda 函数的类型实际上不是 function 类型。更重要的是,lambda 似乎不能很好地与类型推断机制配合使用。
附件是一个小例子,我在其中测试了翻转函数的两个参数以添加两个整数。 (我使用的编译器是 MinGW 下的 gcc 4.6.2。)在示例中,addInt_f 的类型已使用 function 显式定义,而 addInt_l 是一个 lambda,其类型使用 auto 进行类型推断。
当我编译代码时,flip 函数可以接受显式类型定义的 addInt 版本,但不能接受 lambda 版本,给出错误提示,
testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
接下来的几行表明,如果将 lambda 版本(以及“原始”版本)显式转换为适当的函数类型,则可以接受它。
所以我的问题是:
为什么 lambda 函数首先没有
function<>类型?在这个小例子中,为什么addInt_l没有function<int (int,int)>作为类型,而是使用不同的lambda类型?从函数式编程的角度来看,函数/函数对象和lambda有什么区别?如果有根本原因,这两者必须不同。我听说 lambda 可以转换为
function<>,但它们是不同的。这是 C++11 的设计问题/缺陷、实现问题还是将两者区分开来是否有好处?似乎仅addInt_l的类型签名就已经提供了有关函数的参数和返回类型的足够信息。有没有办法编写 lambda 以避免上述显式类型转换?
提前致谢。
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}
【问题讨论】:
-
您不应该使用
std::function参数,主要是因为它禁止类型推断(这是您的问题)。 -
Lambda 被转换为匿名函子(或函数,如果它们不捕获环境)。将它们转换为 std::function 会在语言和库之间引入强耦合,因此将是一个非常糟糕的主意。
-
@MFH
Lambda 始终是匿名函数对象。然后可以将这些函数对象转换为函数指针。 -
@TingL 这就是你错的地方。 lamdas 不是库结构,而是一种新的语言特性。
标签: c++ lambda functional-programming c++11