本文介绍了为仅接受功能的功能定义接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将(f + g)定义为(f + g)(x):= f(x)+ g(x)常规的矩阵加法与此定义是一致的。

Define (f + g) to mean (f + g)(x) := f(x) + g(x). Conventional matrix addition is consistent with this definition.

这是一个简单的实现

template<typename Funcf, typename Funcg>
auto operator+(Funcf f, Funcg g){
  return [f, g](auto x){return f(x) + g(x);};
}

此操作失败是因为 operator + 仅使用用户定义的类型。下次尝试

This fails because operator+ only consumes user defined types. The next attempt gives

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);};
}

此方法有效,并且不会乱丢命名空间。但是,它乱七八糟的间接,并且呼叫站点是丑陋的自动添加= std :: function< int(int)> {f} + std :: function< int(int)> {g} ;

This works and it doesn't litter the namespace. However it litters indirections, and the call-site is ugly auto added = std::function<int(int)>{f} + std::function<int(int)>{g};.

如果允许第一个 operator + (或重命名为添加) ,则呼叫站点会更好,并且可以内联函数。

If the first operator+ was allowed(or was renamed to add), the call site would be nicer, and the functions would be inlined. But it attempts to match against everything, which seems brittle.

是否可以定义一个模板接口来指定输入为函数,但仍可以内联它们,但不能

Is it possible to define a template interface that specifies the inputs are functions, still inlines them, but doesn't pollute the namespace with an overly generic name?

换句话说,是否存在 std :: function 有更方便的呼叫站点?我强烈怀疑答案是否定的。如果答案是否定的,那么在上述两个极端之间是否折衷?

In other words, is there a compile time version of std::function with a more convenient call site? I strongly suspect the answer is no. And if the answer is no, is there a compromise between the above two extremes?

还是选项三,我在想这是错误的方式吗?您将如何在c ++中建模(f + g)?

Or option three, am I thinking about this the wrong way? How would you model (f + g) in c++?

推荐答案

运算符仅适用于用户定义的类型。

Operators only works for user defined types. Then let's make your function be!

我们可以定义一个基本上是lambda的类型,但使用用户定义的类型名称:

We can define a type that is basically a lambda, but with a user defined type name:

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)};
}

这是一个可扩展任何类型并使用其<$ c的类$ c> operator()函数。

This is a class that will extends any type and will use it's operator() function.

现在,您可以使用 addable_lambda 函数:

Now, you can use the addable_lambda function:

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

It's not perfect, but slightly less ugly. Plus, you don't suffers the overhead that std::function adds.

这篇关于为仅接受功能的功能定义接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 10:52