可以将lambda的类型用作模板参数,例如:
template<typename InArg, typename Function>
class selfCompose {
Function f;
public:
selfCompose(Function f): f(f) {}
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>(f)(4) // yields (4²)² = 256
<< std::endl;
return 0;
}
然而,这里对
f
的双重使用有点冗余。我们可以省略传递lambda的类型作为模板(将其转换为适当的std::function
(损失多态性 - 但是C++ lambda无法参数化多态)),但我有一个应用程序,我更喜欢不必将其值传递给构造函数(因为我想使用我的类的初始化本身作为模板参数,在预期特定构造函数签名的情况下)。我希望它能像这样工作:template<class InArg, class Function>
class selfCompose {
Function f;
public:
selfCompose() {} // default constructor for f
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>()(4) << std::endl;
return 0;
}
但是这段代码不能编译,因为Lambda表达式有一个已删除的默认构造函数。对于捕获lambda来说这是不可避免的,但对于像我例子中的简单lambda来说,这对我来说没有太多意义:它们不需要引用任何本地变量。
是否有其他方法可以获得这种功能,还是我必须采用将lambda定义为命名类的老式方法?
struct myFun {
auto operator() (int x) -> int {return x*x;}
};
当然,我想要使用的Lambda函数并不像
x → x²
那么简单,因此仅从几个标准函数类中选择不够灵活。
operator()
。 - leftaroundaboutstruct X {}; X a,b,c;
所有的X
实例等效(具有相同的行为),但不是同一个(具有不同的标识)。我不太明白为什么您不想将lambda作为参数传递,特别是compose<decltype(f)>(5)
和compose(f)(5)
之间有什么不同(我实际上觉得第二个更容易读)。如果您担心可能的优化问题,请不要,编译器知道该做什么。 - David Rodríguez - dribeasselfCompose<int, decltype(f)>
作为模板参数传递给现有类,该类本身将实例化多个不同的参数类实例,并未准备好向构造函数传递任何额外的参数。 - leftaroundabout