0

Hello everyone I need some help. I am trying to make a class that will store a class with an unknown number and type of arguments and I am stuck on one part. I need to call method Click() from the ControlItem class which is inherited from ControlItemBase class. I know that I can NOT use 'virtual function' in this case, it just doesn't work, so I am stuck on this part. I tried to do different casts but that didn't work.

I also found this question Storing a variadic template class into std::vector the guy who answered made almost the same implementation of the code as I did, but he didn't explain how to call the methods in this case.

I hope someone can help me solve this problem, thank you.

class ControlItemBase {
public:
    void OnClick(){
     // HOW TO ACCESS THE ControlItem -> Click() HERE
    }
};

template<class... Args>
class ControlItem : public ControlItemBase{
public:
    std::tuple<Args...> arguments;
    std::function<void(Args...)> func;

    ControlItem(std::function<void(Args...)> func) : func(func){}
    void Click() {
     // Need to call this method
    }
    void SetArgs(std::tuple<Args...> args) {
        arguments = args;
    }
};

class Controls
{
public:
    static std::vector<ControlItemBase> items;

    Controls();
    ~Controls();

    template<class Class, class... Args>
    void AddEventListener(Class* context, void (Class::* func)(Args...), Args... args) {
        ControlItem<Args...> c(std::bind(func, context, args...));
        c.SetArgs(std::make_tuple(std::move(args...)));
        items.push_back(c);
    }

};
  • Regarding _"I know that I can use 'virtual function' in this case"_ -- yes, you can, so why are you not doing that? – paddy Jun 01 '22 at 04:35
  • @paddy Sorry, it was a typo, I meant cannot – Artrm Kovalchuk Jun 01 '22 at 04:38
  • Please explain, why it just doesn't work. The shown code should work. – 273K Jun 01 '22 at 04:39
  • I got it. You got object slicing in `std::vector`. – 273K Jun 01 '22 at 04:41
  • Oh I see. So, you are storing `std::vector items;`. Quite simply, when you do `items.push_back(c);` the result is to discard the actual type of `c` and construct a new value of type `ControlItemBase`. You can't store different arbitrary types _by value_ in a container. Either use something like a variant, or allocate your types dynamically and store something like `std::vector>` – paddy Jun 01 '22 at 04:41

0 Answers0