为只接受函数的函数定义接口
Defining interfaces for functions that only accept functions
定义(f+g(为平均值(f+g((x(:=f(x(+g(x(。传统的矩阵加法与这个定义是一致的。
以下是一个简单的实现
template<typename Funcf, typename Funcg>
auto operator+(Funcf f, Funcg g){
return [f, g](auto x){return f(x) + g(x);};
}
由于operator+
只使用用户定义的类型,因此此操作失败。下一次尝试给出
template<typename R, typename I>
auto operator+(std::function<R(I)> f, std::function<R(I)> g){
return [f, g](auto x){return f(x) + g(x);};
}
这是有效的,并且不会破坏命名空间。然而,它丢弃了间接性,并且调用站点是丑陋的auto added = std::function<int(int)>{f} + std::function<int(int)>{g};
。
如果第一个operator+
被允许(或者被重命名以添加(,那么调用站点会更好,并且函数会内联。但它试图与一切相匹配,这似乎很脆弱。
是否可以定义一个模板接口,指定输入是函数,仍然内联它们,但不会用过于通用的名称污染命名空间?
换句话说,有没有std::function
的编译时版本具有更方便的调用站点?我强烈怀疑答案是否定的。如果答案是否定,那么上述两个极端之间是否存在妥协?
或者选项三,我是不是想错了?您将如何在c++中建模(f+g(?
运算符仅适用于用户定义的类型。那么让我们让你的功能成为!
我们可以定义一个基本上是lambda的类型,但使用用户定义的类型名称:
template<typename F>
struct addable_lambda_impl : F {
template<typename T>
addable_lambda_impl(T f) : F{std::move(f)} {}
using F::operator();
};
template<typename F>
addable_lambda_impl<F> addable_lambda(F f) {
return addable_lambda_impl<F>{std::move(f)};
}
这是一个将扩展任何类型并使用其operator()
函数的类。
现在,您可以使用addable_lambda
功能:
auto lambda = addable_lambda([](){});
实现您的运营商也更容易:
template<typename F, typename G>
auto operator+(addable_lambda_impl<F> f, addable_lambda_impl<G> g){
return addable_lambda([f, g](auto x){ return f(x) + g(x); });
}
它并不完美,但稍微不那么丑陋。此外,您不会遭受std::function
添加的开销。
相关文章:
- 内联如何影响模块接口中的成员函数
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- unique_ptr实现接口时对已删除函数的引用
- 在多个头文件中从接口声明被覆盖的函数时,如何避免重复代码?
- 如何通过接口将函子分配给函数对象
- 如何创建一个接口,允许我访问C++中的按钮(和其他ui)函数,该函数是使用python中的MFC实现的
- C++接口的工厂函数实现
- 对已定义的接口析构函数的未定义引用
- 必须具有泛型接口的函数,但必须根据传递的子类(不知道它们是什么!)以不同的行为 - C++
- 在构造函数处将类对象强制转换为接口始终返回 NULL
- 在接口文件中使用模板时出现"not a type"错误的函数指针
- 从 COM 接口中的函数返回多个值
- 为什么在将多态行为与指向接口的指针一起使用时没有调用析构函数?
- 这是重载提供与非静态成员函数相同接口的静态成员函数的优雅方法吗?
- 从多个不同的实现类 c++ 调用接口函数
- 单冒号是什么意思 c++ 函数接口
- 编写现代函数接口以"produce a populated container"
- 为什么std::vector的构造函数接口在C++11中发生了变化
- 传递函数接口函数的指针
- 为什么shared_ptr无法解析函数接口中的继承关系?