gpt4 book ai didi

c++ - 为只接受函数的函数定义接口(interface)

转载 作者:行者123 更新时间:2023-11-30 05:21:24 24 4
gpt4 key购买 nike

定义 (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+被允许(或重命名为添加),调用站点会更好,并且函数会被内联。但它会尝试匹配一切,这似乎很脆弱。

是否可以定义一个模板接口(interface),指定输入是函数,仍然内联它们,但不会用过于通用的名称污染命名空间?

换句话说,有没有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([](){});

实现您的运算符(operator)也更容易:

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 添加的开销。

关于c++ - 为只接受函数的函数定义接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40166383/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com