简体   繁体   中英

Passing an arbitrary lambda expression to a function?

I have a pretty exotic problem, since I am trying to create some sort of a compiler... I want to pass a lambda expression to a templated function like this:

    template<class T>
delegate<T>* bind(std::function<T> func)
{
    return nullptr;
}

So that I can now call

bind([&](int a) { // do something });

... So normally, this wouldn't be a problem, since std::function is able to capture a lambda. But here the problem is that (let's assume) I don't know or don't want to provide the info about what "T" is exactly. It could be any function signature you could also insert into std::function<>...

I also need to pass this "inferred" signature back to the "delegate" class I want to return and that delegate class needs to be a pointer to class...

For now I have come up with this:

template<class T>
struct delegate : public std::function<T>
{
    delegate(const std::function<T>& func) : std::function<T>(func) { }
    delegate(const delegate<T>& func) { }
};

template<class T>
delegate<T>* bind(std::function<T>&& func)
{
    return new delegate<T>(std::forward<std::function<T>>(func));
}

But the above example of a call to "bind" fails with "failed template argument deduction". How can I get this to work without having to specify the "T" parameter explicitly when calling "bind" (then it works, at least)?

Since in theory my compiler has all the info to workaround this issue, I could just insert the instance of "T", but this would make the generated code unnecessarily convoluted.

BTW, I am using the lastest Clang compiler.


Here is the final solution:

    template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> struct get_signature<Ret(Mem::*)(Args...) const> {
    typedef Ret type(Args...);
};

template<class T> 
delegate<typename get_signature<decltype(&T::operator())>::type>* bind(T func)
{
    return nullptr;
}

Be aware that you may need to adjust the "const" modifiers to your needs.

First, you have completely screwed up your rvalue references. Your forwarding does not work at all.

Secondly, that's impossible in some cases.. For some function objects , you could infer the signature by taking the member function pointer to operator() and inspecting it's signature. But for others, they will be overloaded and it will not work.

template<typename T> struct get_signature;
template<typename Mem, typename Ret, typename... Args> 
struct get_signature<Ret(Mem::*)(Args...)> {
    typedef Ret(Args...) type;
};

template<class T> 
delegate<typename get_signature<&T::operator()>::type>* bind(T func)
{
    return nullptr;
}

Thirdly, std::bind ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM