我正在尝试使用C++11的函数式特性。其中一个奇怪的事情是,lambda函数的类型实际上不是function<>类型。而且,lambda似乎并不完全适用于类型推断机制。
以下是一个小例子,我在其中测试了将两个整数相加的函数的两个参数交换的情况。(我使用的编译器是MinGW下的gcc 4.6.2) 在此示例中,addInt_f的类型已明确定义为function<>,而addInt_l是使用auto进行类型推断的lambda。
当我编译代码时,flip函数可以接受显式定义类型版本的addInt,但不能接受lambda版本,会出现错误,提示“testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
接下来几行显示,如果将lambda版本(以及“原始”版本)显式强制转换为适当的function<>类型,则可以接受它们。
因此,我的问题是:
1.lambda函数为什么一开始就没有function<>类型?在这个小例子中,为什么addInt_l的类型不是function,而是不同的lambda类型?从函数式编程的角度来看,函数/函数对象和lambda之间有什么区别?
2.如果这两者必须有根本性的不同,那么为什么?我听说lambda可以转换为function<>,但它们是不同的。这是C++11的设计问题/缺陷,还是实现问题,或者区分这两者有好处?似乎addInt_l的类型签名已经提供了关于函数的参数和返回类型足够的信息。
3.有没有一种方法可以编写lambda,使得可以避免上述显式类型转换?
谢谢。
以下是一个小例子,我在其中测试了将两个整数相加的函数的两个参数交换的情况。(我使用的编译器是MinGW下的gcc 4.6.2) 在此示例中,addInt_f的类型已明确定义为function<>,而addInt_l是使用auto进行类型推断的lambda。
当我编译代码时,flip函数可以接受显式定义类型版本的addInt,但不能接受lambda版本,会出现错误,提示“testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
接下来几行显示,如果将lambda版本(以及“原始”版本)显式强制转换为适当的function<>类型,则可以接受它们。
因此,我的问题是:
1.lambda函数为什么一开始就没有function<>类型?在这个小例子中,为什么addInt_l的类型不是function,而是不同的lambda类型?从函数式编程的角度来看,函数/函数对象和lambda之间有什么区别?
2.如果这两者必须有根本性的不同,那么为什么?我听说lambda可以转换为function<>,但它们是不同的。这是C++11的设计问题/缺陷,还是实现问题,或者区分这两者有好处?似乎addInt_l的类型签名已经提供了关于函数的参数和返回类型足够的信息。
3.有没有一种方法可以编写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
作为参数,因为它会抑制类型推导(这也是你在这里遇到的问题)。 - R. Martinho Fernandes