jeudi 20 octobre 2016

Defining interfaces for functions that only accept functions

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

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+ 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?

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?

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

Aucun commentaire:

Enregistrer un commentaire