Polymer - 1 year ago 49

C++ Question

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

Here is a naive implementation

`template<typename Funcf, typename Funcg>`

auto operator+(Funcf f, Funcg g){

return [f, g](auto x){return f(x) + g(x);};

}

This fails because

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

}

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

If the first

`operator+`

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?

In other words, is there a compile time version of

`std::function`

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

Answer Source

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

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

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

function.

Now, you can use the `addable_lambda`

function:

```
auto lambda = addable_lambda([](){});
```

Implementing your operator is easier too:

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

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

adds.