I am developing a relatively simple program (a calculator actually). However, I have decided to make all components of my program as generic as possible because:
- It's good practice.
- It keeps things interesting.
As part of this program I am using a Tuple
class that I am writing. I know that a class already exists, but I like having complete control over my code and this is only an exercise.
One thing I need to do is transform a tuple of expressions (where expressions themselves are generic) into a tuple containing the result of the expressions' evaluations. In short, I have (with trivial parts left out):
template <class T>
class Expression {
public:
virtual T Eval() = 0;
// ...
};
template <class First, class ... Rest>
class Tuple {
// ...
private:
First first;
Tuple<Rest ...> rest;
};
And I would like to specialize over a tuple of a generic type like this:
template <template <class> class R, class First, class ... Rest>
class Tuple<R<First>, R<Rest> ...> {
// and here is the problem:
Tuple<First, Rest ...> Transform(function<template<class T> T(R<T>)>);
};
After which I could do this:
template <class T> // There has to be a better way to do this
T Eval(Expression<T>& expr){
return expr.Eval();
}
// ...
Tuple<First, Rest ...> tuple = exprs.Transform(Eval);
There are a few places here where I am not sure how to go about things and a real expert who could help me out here would be appreciated. I expect this code will not compile because of minor flaws but that isn't the point - My primary worry is the line I marked. If I recall correctly from the brief period I learned Haskell this function should be of Rank-2 (If not please comment and I will remove the tag). It just doesn't look right. Is there any way to do this?
Update:
I was advised to try pass a functor with a generic operator ()
as a template argument but that didn't work either.