progschj / ThreadPool

A simple C++11 Thread Pool implementation
zlib License
7.85k stars 2.24k forks source link

How can We Use A override member Function in threadpool enqueue ? #66

Open z80sui opened 5 years ago

z80sui commented 5 years ago

class A { virture void a() = 0; }; class B:public A { void a(){} override; }; how can I use override function a like this? A a = new B(); enqueue( &a->a, this)

z80sui commented 5 years ago

@progschj

z80sui commented 5 years ago

@wilx please have a look

fogti commented 5 years ago

With C++11 the following should be possible...

std::shared_ptr<A> a = std::make_shared<B>();
tp.enqueue([a]() { a->a(); });
vG5YtZQN commented 5 years ago
#include <iostream>

template<typename Ft, class Cp, class ...Args>
void enqueue(Ft &&ft, Cp &&cp, Args &&...args) {
    (cp.*ft)(args...);
}

class A {
public:
    virtual void a() = 0;
};

class B : public A {
    void a() override {
        std::cout << "B called" << std::endl;
    }
};

class C : public A {
    void a() override {
        std::cout << "C called" << std::endl;
    }
};

int main() {
    A *a1 = new B{};
    A *a2 = new C{};
    enqueue(&A::a, *a1);
    enqueue(&A::a, *a2);
}
vG5YtZQN commented 5 years ago

if you would like a more ugly version,take a look like this...

#include <iostream>
#include <functional>

template<bool, typename Ft, class ...Args>
struct call_member_function_impl;

template<typename Ft, class ...Args>
struct call_member_function_impl<false, Ft, Args...> {
public:
    static void call(Ft &&ft, Args &&...args) {
        ft(args...);
    }
};

template<typename Ft, class ...Args>
struct call_member_function_impl<true, Ft, Args...> {
public:
    template<typename Caller, typename Ins, class ...Parms>
    static void call(Caller &&ft, Ins &&ins, Parms &&...args) {
        (ins.*ft)(args...);
    }
};

template<typename Ft, class ...Args>
void call_member_function_if_possible(Ft &&ft, Args &&...args) {
    typedef call_member_function_impl<std::is_member_function_pointer<Ft>::value, Ft, Args...> type;
    type::template call<Ft, Args...>(std::forward<Ft>(ft), std::forward<Args>(args)...);
};

class A {
public:
    virtual void a() = 0;
};

class B : public A {
    void a() override {
        std::cout << "B called" << std::endl;
    }
};

class C : public A {
    void a() override {
        std::cout << "C called" << std::endl;
    }
};

int main() {
    A *a1 = new B{};
    A *a2 = new C{};
    call_member_function_if_possible(&A::a, *a1);
    call_member_function_if_possible(&A::a, *a2);
}