Hobbyist
Hobbyist

Reputation: 925

What is the syntax for storing a specific class's member functions in a vector?

I did quite a bit of searching, but the combination of * () and class scope has greatly hindered me in understanding of the syntax, with each edit throwing a new error, any help guys?

What I'm trying to do:

Declare a std::vector of pointers to member functions found in MyClass.h

Assign the actual member functions to the std::vector in MyClass.cpp's constructor

The member functions are not static

Thanks!

Upvotes: 0

Views: 61

Answers (2)

Peter R
Peter R

Reputation: 2985

I'm curious where you're going to use them from. You see in order to call a C++ class member function you need to have an instance pointer with which to call it (each member function needs a this in order to access the class state). So normally you'd wrap the member function pointer together with the instance pointer with std::bind and then maybe store the result in std::function. To put them in vector they're all going to need the same signature.

Is this the kind of thing you were looking for:

class P
{
    typedef std::function<void (void)> func_t;
    std::vector<func_t> functions;
public:
    P()
    {
        functions.push_back(std::bind(&P::foo1, this));
        functions.push_back(std::bind(&P::foo2, this));
        functions.push_back(std::bind(&P::foo3, this));
    }
    void foo1(void)
    {
        std::cout << "foo1\n";
    }
    void foo2(void)
    {
        std::cout << "foo2\n";
    }
    void foo3(void)
    {
        std::cout << "foo3\n";
    }
    void call()
    {
        for(auto it = functions.begin(); it != functions.end(); ++it)
        {
            (*it)();
        }
    }
};

int main()
{
    P p;
    p.call();
}

After further clarification from the OP I'll propose this:

class P
{
    typedef std::function<void (void)> func_t;
    std::map<const char*, func_t> functions;
public:
    P()
    {
        functions["foo1"] = std::bind(&P::foo1, this);
        functions["foo2"] = std::bind(&P::foo2, this);
        functions["foo3"] = std::bind(&P::foo3, this);
    }
    void foo1(void)
    {
        std::cout << "foo1\n";
    }
    void foo2(void)
    {
        std::cout << "foo2\n";
    }
    void foo3(void)
    {
        std::cout << "foo3\n";
    }
    void call_by_name(const char* func_name)
    {
        functions[func_name]();
    }
};

int main()
{
    P p;
    p.call_by_name("foo1");
    p.call_by_name("foo2");
    p.call_by_name("foo3");
}

Upvotes: 2

Qaz
Qaz

Reputation: 61910

You can use member function pointers like this (the C++11 is unrelated to that part):

struct S {
   int foo(){std::cout<<"foo"; return 0;}
   int bar(){std::cout<<"bar"; return 0;}
};

int main() {
   std::vector<int(S::*)()> funcs{&S::foo, &S::bar};

   S s;
   for (auto func : funcs) {
      (s.*func)();
   }
}

However, if you use C++11, std::function can make it a bit cleaner:

std::vector<std::function<int(S &)>> funcs{&S::foo, &S::bar};

S s;
for (auto func : funcs) {
   func(s);
}

If you use C++03, Boost has boost::function, which is similar.

Upvotes: 2

Related Questions