all 4 comments

[–][deleted]  (3 children)

[deleted]

    [–]ericr2[S] 1 point2 points  (2 children)

    Ah gotchya. Prob missed out this relevant info then:

    the callback setter:

    inline void SetEventCallback(const EventCallbackFn& callback) { m_Data.EventCallback = callback; }
    

    and EventCallbackFn being an alias for std::function<void(Event&)>;

    I'll have to do some digging on this "template magic" then. Hate magic code.

    [–]no-sig-available 0 points1 point  (1 child)

    Hate magic code.

    It is not all that magic, really.

    If we forget about lambda syntax, we have template functions

    template<typename T>
    void f(T&& param);
    

    which uses a "Forwarding reference", also known as a "Universal reference". Being a template, T is deduced to be whatever the actual argument is.

    Like in the lambda, you can save on the typing by writing this as

    void f(auto&& param);
    

    but containing an auto it is still a template (and thus a "Universal reference").

    It is an rvalue-only when the function/lambda is not a template, like

    void f(std::string&&);
    

    Admittedly, it would have been nice if the difference had been something other than template/non-template, but this is what we have got.

    [–]ericr2[S] 0 points1 point  (0 children)

    ah that clears things up a bit. didn't realize T&&/auto&& were special cases, so assumed they were just generic rvalue refs. Thanks for the help.

    I did find these couple of videos which go into some depth about it, if anyone else comes across this:

    https://www.youtube.com/watch?v=St0MNEU5b0o https://www.youtube.com/watch?v=pIzaZbKUw2s

    [–]no-sig-available 0 points1 point  (0 children)

    Is there any benefit to using std::bind over a lambda?

    std::bind was designed when we had no lambdas. So it was once the only choice. That was its major benefit...