Passing a template variable to a template in C ++ 14
I am writing a compiler that compiles in C ++ and I am having problems with the type of C ++ code. The language is supposed to be lazy, so we have a lazy value wrapper, Chunk. Here is a part of it, as well as the problematic code:
#include <functional>
#include <memory>
template<class T>
class Chunk
{
public:
Chunk();
Chunk(std::function<T()> f);
T operator()();
std::function<T()> f_;
private:
std::shared_ptr<T> cache_;
};
template<class T>
T Chunk<T>::operator()()
{
if(cache_ == nullptr)
cache_ = std::make_shared<T>(f_());
return *cache_;
}
template<class T, class F>
T operator*(Chunk<T> t1, Chunk<F> t2)
{
return t1() * t2();
}
template<class T, class... Args>
T apply(Chunk<std::function<T(Args...)>> c, Args... as)
{
return c()(as...);
}
template<class F>
auto toChunk(F f) -> Chunk<decltype(f())>
{
return Chunk<decltype(f())>(f);
}
template<class T, class F>
struct ops
{
static const auto multiply =
toChunk([]() { return ops::multiply_; });
static const auto multiply_(Chunk<T> x, Chunk<F> y) -> decltype(x * y)
{
return x * y;
}
};
int main()
{
Chunk<double> t = toChunk([]() { return 1.0; });
Chunk<float> f = toChunk([]() { return 2.0f; });
apply(ops::multiply, t, f);
return 0;
}
I am unable to define a definition multiply
to make this work without getting an error used without template parameters
. (There might be a second problem here because it is multiply_
n't std::function
, but the compiler breaks the absence of template parameters first.)
I could write a lot of overloads for each pair of types, but that's just really ugly. I tried making a multiple template variable without a template class, and although I'm using C ++ 14, getting cannot resolve address of overloaded function
at multiply_
with this alternative definition:
template<class T, class F>
auto multiply_(Chunk<T> x, Chunk<F> y) -> decltype(x * y)
{
return x * y;
}
template<class T, class F>
Chunk<decltype(multiply_)> multiply = toChunk([]() { return multiply_; });
Of course, I changed ops::multiply
to simple multiply
. Any suggestions on how to overcome this?
source to share
I ended up using a completely different solution. I have overloaded apply
by adding this second definition:
template<class F, class... Args>
auto apply(F f, Args... as) -> decltype(f(as...))
{
return f(as...);
}
And rewritten to multiply is simple:
auto multiply = [](auto x, auto y) { return x * y; };
This way, our library functions will not be in lazy wrappers, whereas custom functions (which cannot be templates in our language).
source to share