1

Why do I get the following compiler error

error: no matching function for call to 'memo(drawConnections_nicer2(const RangeVector&, std::function)::__lambda13)' });

with this code?

template<typename R, typename ... Args>
shared_ptr<function<R(Args...)> > memo(function<R(Args...)> fn)
{
    map<tuple<Args...>,R> table;
    return make_shared<function<R(Args...)> >([fn,table](Args... args) mutable ->
            R {
        auto argt = make_tuple(args...);
        auto memoized = table.find(argt);
        if(memoized==table.end())
        {
            auto result = fn(args...);
            table[argt]=result;
            return result;
        }
        else
        {
            return memoized->second;
        }
    });
}

...

shared_ptr<function<int(Range,int)> >  calculate_level = memo([&](Range current, int pos) ->
int {
    auto max_level = 0;
    for(auto i=pos;i>=0;i--)
    {
        auto other = drawn[i];
        if ( !(other.second<current.first || other.first>current.second) ) // intersects
        {
            max_level = max(max_level, (*calculate_level)(other,i-1)+1);
        }
    }
    return max_level;
});

I thought that the lambda should be wrapped in a function object automatically here? Why is this not the case? Can I make do without the function parameter in memo?

tux3
  • 7,171
  • 6
  • 39
  • 51
user1415913
  • 325
  • 4
  • 9
  • Each lambda instance has its own type and that type is not derived from `function<>`, check this for example: http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda/ – c-smile Mar 09 '15 at 21:26
  • @T.C. "duplicate" hammer answers your main question. But looking at the rest of your post: Your second problem is your design is fundamentally flawed, as capturing a shared_ptr by REFERENCE doesn't extend its lifetime. A better question would be "how do I automatically memoize": I'd advise to write a Y-Combinator and interpose the memoization helper there (C++14 support required, but most C++11 compilers support it I think?) This would both solve your technical issue, and let you reach your goal. [here](http://stackoverflow.com/a/25085574/1774667) is a primitive C++1y Y-combinator. – Yakk - Adam Nevraumont Mar 09 '15 at 21:29
  • Aha! Here is a y-combinator esque thing that sucks less: http://coliru.stacked-crooked.com/a/4ba95aac15acde25 -- change `operator()` to pass in `*this` as the first argument, and interpose the memoization table there, and have the lambda recurse with `self(args...)` instead of `self(self,args...)` and I think that would solve your problem. This does answer the question: the signature should be `Y: (F:((Args->R),Args)->R) -> (Args->R)` not `Y: (F:(F,Args)->R) -> (Args->R)`, as the first allows this memoization insertion in the recursion. – Yakk - Adam Nevraumont Mar 09 '15 at 21:34

0 Answers0