将常规函数绑定到 std::function
Binding of regular function to std::function
我正在尝试使用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)
语法组合常规函数。
想到
的唯一想法是从一些假人开始:
struct F{}F;
function<int(int)> operator*(struct F, function<int(int)> g)
{
return g;
}
function<int(int)> operator*(function<int(int)> f, function<int(int)> g)
{
return [=](int x){ return f(g(x));};
}
int main()
{
cout<<(F*f*g)(5)<<endl; // start with F, then add the real stuff
}
正如 Daniel 指出的,运算符重载中的一个参数必须是类或枚举类型。因此,需要实例化function<int(int)>
对f*g
的调用,而不是函数指针类型。此问题有两种选择,
-
使用函数代替运算符,例如
template<typename T> function<int(int)> multi(T x, T y)
-
将其中一个函数参数声明为"函数">
template<typename T> function<int(int)> operator*(function<int(int)> x, T y)
相关文章:
- Confusion: decltype vs std::function
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 传递给std::function template的template参数究竟代表什么
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 将函数包装器转换为 std::function
- 类型擦除的std::function与虚拟函数调用的开销
- C++ std::function 对于类 exept 的所有实例都是空的(只有 Visual2019 编译器问题)
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将 lambda 表达式传递给 std::function in C++
- 模板类的部分模板专用化,如 std::function
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 从 std::function in C++ 访问模板化 lambda
- 什么是 std::function::argument_type 的替代品?
- C++派生类重载函数(带有 std::function 参数)不可见
- 如何在 qi 符号表中使用 std::function
- 将 std::function 与模板一起使用
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 我需要在 std::function 上使用 unique_ptr 吗?
- 如何将函数指针从 std::function 传递到 Linux 克隆?