我正在尝试使用带有lambda函数参数的模板类。但是,我不明白如何传递参数。这是我到目前为止所尝试的内容:
#include <iostream>
using namespace std;
template <class F>
class A {
public:
int f(int i)
{
return F(i); //*
}
};
int main(int argc, const char * argv[]) {
auto f = [](int i){return i+5;};
A<decltype(f)> a;
cout << a.f(5);
return 0;
}
我在标记的行中收到错误。
有人可以帮忙吗?
答案 0 :(得分:8)
您的示例不起作用,因为F
是类型,而不是可调用对象。下一步是通过创建成员变量来实例化它。
template <class F>
class A {
F function;
public:
int f(int i) {
return function(i);
}
};
但是,由于删除了lambda默认构造函数,因此仍然无法工作。这意味着我们需要另一种方法来构建function
。这可以通过将参数传递给A
的构造函数来实现。
template<typename F>
class A {
F function;
public:
A(const F& f) : function(f) {}
int f(int i) {
return function(i);
}
};
// ...
auto f = [](int i) { return i+5; };
A<decltype(f)> a(f);
这使用了lambda拷贝构造函数,它没有被删除。
如果你想让它与任何lambda一起使用,你可以添加更多魔法。
template<typename F>
class A {
F function;
public:
A(const F& f) : function(f) {}
template<typename ...Args>
auto f(Args... args) -> std::result_of_t<F(Args...)> {
return function(std::forward<Args>(args)...);
}
};
答案 1 :(得分:3)
如果你真的想使用模板来接受任何类型的功能签名,那么实现应该类似于:
class A {
public:
template<typename F, typename... Args>
auto f(F&& funct, Args&&... args) {
return funct(std::forward<Args...>(args)...);
}
};
那是因为你在评论中说过:
问:仅在方法
F
的类中是否需要类型f
?
答:只有方法。
因此,当你可以使用模板方法时,拥有模板类应该没用。
这里是一个示例,如何调用只调用&#34;可调用对象及其参数&#34; 的方法,在本例中为lambda函数:
int main(int argc, char* argv[]) {
A a;
a.f([](int i) -> int { return i + 5; }, 12);
// |------callable object-----------| |argument of function|
return 0;
}
实际上,方法f
接受第一个参数a&#34; 可调用对象&#34;并且作为进一步的参数,为了调用第一个参数而请求任何参数。
如果要向方法f
传递某种类型的函数签名,例如:int (*)(int)
,则可以避免使用模板并传递std::function
类型的对象。
这只是一个例子:
#include <functional>
class A {
public:
// method g accept a function which get a integer and return an integer as well.
int g(std::function<int(int)> funct, int arg) {
return funct(arg);
}
};
答案 2 :(得分:2)
将A
定义为继承自或以某种方式包含lambda函数是不够的,在创建A
实例时仍需要初始化子对象。
为此,作为示例,您可以从lambda继承并使用A
作为可调用对象。
它遵循一个最小的工作示例:
#include <iostream>
using namespace std;
template <class F>
class A: public F {
public:
A(F f): F(f) {}
};
int main() {
auto f = [](int i){return i+5;};
A<decltype(f)> a{f};
cout << a(5);
return 0;
}
您不必定义任何函数f
来执行 lambda。
无论如何,如果你想让一个函数f
被称为a.f(5)
,你可以按照以下方式定义它:
int f(int i) {
return F::operator()(i);
}
或者如下:
int f(int i) {
return (*this)(i);
}