我正在尝试使用 C++ 中的运算符重载来编写函数式组合,以便拥有类似于函数式语言(例如 Haskell)中的简单组合语法。我的目标是在组合中使用常规的裸 C++ 函数。到目前为止,我编写了两个重载:
operator%
它使用两个function<int(int)>
参数和operator*
它使用模板类型作为参数。
operator%
效果很好,但是在 main() 中,我首先必须将常规函数包装到其中function<int(int)>
以便operator%
接受它们作为输入参数。我想通过将它迁移到operator*
使用模板参数的重载来避免这个额外的步骤。我以为可以将正则函数绑定到 的模板参数上operator*
,但是编译器报错:
composingFunc.cpp11.cpp: In function ‘int main()’:
composingFunc.cpp11.cpp:28:12: error: invalid operands of types ‘int(int)’ and ‘int(int)’ to binary ‘operator*’
cout<<(f*g)(5)<<endl;
你知道如何解决这个问题吗?在中使用模板参数operator*
不是强制性的 - 如果您有其他方法,只需在此处建议。
这是源代码:
#include<iostream>
#include<functional>
using namespace std;
int f(int n)
{ return 2*n; }
int g(int n)
{ return n+1; }
function<int(int)> operator%(function<int(int)> f, function<int(int)> g)
{
return [=](int x){ return f(g(x));};
}
template<typename T>
function<int(int)> operator*(const T &f, const T &g)
{
function<int(int)> f1=f,f2=g; //this is encapsulated here so it is not
//necessary to repeat the same in main
//for every functional composition
return [=](int x){ return f1(f2(x));};
}
int main()
{
function<int(int)> f1=f, f2=g; //I want to encapsulate this step into operator*
cout<<(f1%f2)(5)<<endl; //this works well
cout<<(f*g)(5)<<endl; //error in this line
}
编辑: Zac 给出的解决方案对函数参数之一使用类类型(根据标准,在运算符重载中必须使用至少一个枚举或类类型参数)和模板类型参数。然后常规 C++ 函数很乐意绑定到这两个参数。因此最终的运算符重载非常简单:
template<typename T>
function<int(int)> operator*(function<int(int)> f, T g)
{
return [=](int x){ return f(g(x));};
}
然后可以使用简单的(f*g)(x)
语法组合常规函数。