我正在尝试编写一个带有重载构造函数的类,它接受std :: function对象作为参数,但当然每个该死的东西都可以隐式地转换为任何签名的std :: function.这自然是非常有用的.
例:
class Foo {
Foo( std::function<void()> fn ) {
...code...
}
Foo( std::function<int()> fn ) {
...code...
}
};
Foo a( []() -> void { return; } ); // Calls first constructor
Foo b( []() -> int { return 1; } ); // Calls second constructor
Run Code Online (Sandbox Code Playgroud)
这将无法编译,抱怨两个构造函数基本相同且含糊不清.当然,这是无稽之谈.我尝试过enable_if,is_same和其他一些东西.接受函数指针是不可能的,因为这会阻止有状态lambda的传递.当然必须有办法实现这一目标吗?
我害怕,我的模板技能有点缺乏.普通的模板类和函数很容易,但使用编译器玩傻傻的玩家有点超出了我的联盟.有人可以帮帮我吗?
我之前已经知道这个问题的变体,但它们通常关注的是正常的函数而不是构造函数; 或者通过参数而不是返回类型进行重载.
C++ 11同时具有lambda和std :: function <>,但不幸的是,它们有不同的类型.一个结果是,人们无法直接在高阶函数中使用lambda,例如lisp中的map.例如,在以下代码中
#include <vector>
#include <functional>
using namespace std;
template <typename A,typename B>
vector<B> map(std::function<B (A)> f, vector<A> arr) {
vector<B> res;
for (int i=0;i<arr.size();i++) res.push_back(f(arr[i]));
return res;
}
int main () {
vector<int> a = {1,2,3};
map([](int x) -> int { return x;},a); //not OK
auto id_l = [](int x) -> int { return x;};
map(id_l,a); //not OK;
function<int (int)> id_f = id_l;
map(id_f,a); //OK
return 0;
}
Run Code Online (Sandbox Code Playgroud)
,直接使用lambda作为main()的第2行将无法正常工作.g++ -std=c++11 testfunc.cpp返回`... testfunc.cpp:14:37:注意:'main():: __ lambda0'不是从'std …