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?

+3


source to share


2 answers


ops

is the name of the class template. To refer to members of a class template outside of its definition, you need to provide template arguments.



If you fix this error, there will be more.

+2


source


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).

0


source







All Articles