Home > Enterprise >  add to queue a template function c
add to queue a template function c

Time:06-08

i search on google how to store and to execute functions (template function or not) passing in queue but i didn't find an enough good answer...

this is my code

Window.h

struct QueueEventFunction {

    std::vector<std::function<void()>> v;  // stores the functions and arguments
                                           // as zero argument lambdas

    template <typename F,/*template <typename U, typename = std::allocator<U> >*/ typename ...Args>
    void Enqueue(F (*f), Args... args)
    {
        v.push_back([=] { f(args...); });  // add function and arguments
                                           // as zero argument lambdas
                                           // that capture the function and arguments
    }

    void CallAll()
    {
        for (auto f : v)
            f();                              // calls all the functions
    }
};

class Window : public sf::RenderWindow {
public:
    Window(sf::VideoMode window, const std::string& title, sf::Uint32 style = 7U, sf::ContextSettings settings = sf::ContextSettings());
    ~Window();
    template <typename F, /*template <typename ...U > */typename ...Args>
    void addQueue(F (*f), Args...args);
    void execQueue();
    
private:
    QueueEventFunction queue;
}

template <typename F, /*template <typename ...U >*/ typename ...Args>
void Window::addQueue(F (*f), Args...args) {
    queue.Enqueue(f, std::forward<Args>(args)...);
}

void Window::execQueue() {
    queue.CallAll();
}

TestWindow.cpp

template<typename T>
void add(T a, T b) {
    return a   b;
}

class foo{
public:
    template<typename T> T add( T a, T b){ return a  b;}
};

int main() {
        Window window(sf::VideoMode(600, 600), "Test Window",7U,sf::ContextSettings());
        window.addQueue(add<int>,1,2);                  // doesn't work
        foo bar;
        window.addQueue(&foo::add<int>,1,2);    // doesn"t work
        window.addQueue(bar.add<int>(1,2));    // doesn"t work
        return 0;
    }

i got a external symbol error. and if i put a function member class it simply doesn't work. (compilation error)

have you got an idea to correctly make the function addQueue<> with args ?

CodePudding user response:

The big problem with your code is that you take the function pointer as a pointer

template <typename F, typename ...Args>
void Enqueue(F (*f), Args... args)

and

template <typename F, typename ...Args>
void addQueue(F (*f), Args...args);

What you really want is

template <typename F, typename ...Args>
void Enqueue(F f, Args... args)

and

template <typename F, typename ...Args>
void addQueue(F f, Args...args);

And then you can pass any callable thing. Then you can use it with results of bind, lambdas, class member functions, class static member functions, and normal functions.

Then you can use it like

template<typename T>
int add(T a, T b) {
    std::cout << "add(" << a << "," << b << ") -> " << a b << "\n";
    return a   b;
}

class foo{
public:
    template<typename T>
    T add( T a, T b) {
        std::cout << "foo::add(" << a << "," << b << ") -> " << a b << "\n";
        return a   b;
    }

    template<typename T>
    static T static_add( T a, T b) {
        std::cout << "foo::static_add(" << a << "," << b << ") -> " << a b << "\n";
        return a   b;
    }
};

int main() {
    Window window(sf::VideoMode(600, 600),"Test Window",7U,sf::ContextSettings());

    foo bar;
    auto bar_add = [&bar](auto a,auto b){ return bar.add<int>(a,b); };
    auto bind_add = std::bind(&foo::add<int>, &bar, std::placeholders::_1, std::placeholders::_2);

    window.addQueue(bind_add,5,2);
    window.addQueue(bar_add,5,2);
    window.addQueue(add<int>,5,2);
    window.addQueue(foo::static_add<int>,5,2);

    window.execQueue();
    return 0;
}

Try it here https://www.onlinegdb.com/t9WczrL-c

  • Related