0

I am trying to create a class/struct that can take in a struct/class of different types that all have the function update(). I want to get the update() function and then put it in a vector as a pointer and then call it later, but I'm having trouble putting member function pointers into a vector, but I am having no problem putting 'classless' function pointers into the vector.

How can I put the member function pointers into the vector?

Here is my code

#include <vector>
#include <iostream>
#include <stdio.h>

using namespace std;

struct typeA
{
public:
    int data = 0;

    void update()
    {
        cout << "hello, my data is " << data << endl;
    }
};

struct typeB
{
    float data = 0;

    void update()
    {
        cout << "hi, my data is " << data << endl;
    }
};

class typeListTwo
{
    typedef void(*updaterFunc)();
    vector <updaterFunc> items;

public:
    typeListTwo()
    {

    }

    ~typeListTwo()
    {
        items.~vector();
    }

    void addItem(updaterFunc newItem)
    {
        items.push_back(newItem); //This works
    }

    void doWork()
    {
        for (unsigned int funcIndex = 0; funcIndex < items.size(); funcIndex++)
        {
            items[funcIndex]();
        }
    }

};

class typeList
{
    typedef void(*updaterFunc)();
    vector <updaterFunc> items;

public:

    typeList()
    {

    }

    ~typeList()
    {
        items.~vector();
    }

    template <class Item>
    void addItem(Item newItem)
    {
        items.push_back(newItem.update); //But this does not?
        //newItem.update(); //This also works by itself
    }

    void doWork()
    {
        for (unsigned int funcIndex = 0; funcIndex < items.size(); funcIndex++)
        {
            items[funcIndex]();
        }
    }

};

void aFunc()
{
    cout << "123 hello" << endl;
}

void bFunc()
{
    cout << "456 goodbye" << endl;
}

int main()
{
    typeA aThing;
    typeB bThing;
    typeList listThings;
    typeListTwo listThingsTwo;

    aThing.data = 128;
    bThing.data = -3.234;

    listThings.addItem(aThing);
    listThings.addItem(bThing);
    listThings.doWork();

    listThingsTwo.addItem(aFunc);
    listThingsTwo.addItem(bFunc);
    listThingsTwo.doWork();

    return 0;
}
null
  • 171
  • 1
  • 9
  • 4
    Read about [`std::function`](http://en.cppreference.com/w/cpp/utility/functional/function), [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind) and [lambda expressions](http://en.cppreference.com/w/cpp/language/lambda) for ways to solve your problem. – Some programmer dude Feb 09 '18 at 08:55
  • 1
    In C++ member function pointer does not carry information about the object it should be invoked on... – W.F. Feb 09 '18 at 08:56
  • Also read: https://isocpp.org/wiki/faq/pointers-to-members – UnholySheep Feb 09 '18 at 08:56
  • Possible duplicate of [Function pointer to member function](https://stackoverflow.com/questions/2402579/function-pointer-to-member-function) – UKMonkey Feb 09 '18 at 09:05
  • 2
    do not do that `items.~vector();` Read about destructors - http://en.cppreference.com/w/cpp/language/destructor – PiotrNycz Feb 09 '18 at 09:06

1 Answers1

0

The way to go is to use std::function or use interface:

class typeList
{
    std::vector<std::function<void()>> items;
public:

    template <class Item>
    void addItem(Item& item)
    {
        // Care: life time of item should be bigger than this instance
        items.push_back([&](){ item.update(); });
    }

    void doWork()
    {
        for (auto& f : items)
        {
            f();
        }
    }
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • This works, but I do not understand how `items.push_back([&](){ item.update(); });` works – null Feb 09 '18 at 10:05
  • After reading I think I understand that the `[&]() { item.update(); }` is 'capturing' item.update as a 'class data member' by reference – null Feb 09 '18 at 10:20
  • You capture only the variable `item`. then when called (in `doWork`), we call `update` on it. – Jarod42 Feb 09 '18 at 10:30