vendredi 29 septembre 2017

Access violation on std::function assigned to a lambda

I was trying to play around with std::function and std::bind and I stepped in a problem. I would like to build a general structure that allows me to bind a std::function to a member function without knowing a priori the arguments of the member function. I wrote this thing

template<typename Class, typename Return, typename ...Args>
struct Caller
{
private:
    std::function<Return(Args ...)> callerFunction;

    Caller(const Caller&) = delete;
    Caller(Caller&&) = delete;
    Caller& operator=(const Caller&) = delete;

public:
    ~Caller() = default;
    Caller() = default;

    Caller(Class& instance, Return(Class::*function)(Args...))
    {
        callerFunction = [&](Args... args) { return (instance.*function)(args...); };
    }

    Return operator() (Args ... args)
    {
        return callerFunction(args...);
    }
};

FYI I know that the arguments to the function are passed by value (I encountered some problem using universal references with variadic template, I will work on that later).

The problem here is that when I fire the function with operator() I get an Access Violation Error. I tried to narrow down the problem and created a structure without the variadic arguments (allowing the member function to have just an int as argument) and I saw that assigning the lambda to the std::function was given me the same error, but if I used std::bind with a placeholder everything was just fine.

The test ground is this

class A
{
public:
    bool foo(int a)
    {
        std::cout << a << std::endl;
        return true;
    }
};

int main()
{
    A a;
    a.foo(9);

    Caller<A, bool, int> caller(a, &A::foo);
    caller(10);

    std::cin.ignore();
}

Using the lambda, do I need to save the instance of the class in order to call properly the member function?

Aucun commentaire:

Enregistrer un commentaire