Passing a set of pointers to member functions of a template class

81 Views Asked by At

I have here a minimized version of code below, that won't compile.

#include<iostream>
#include<vector>
#include<set>
template<int D>
class Points{
public:
    std::vector<int> data;
    void func1()
    {
        // some operation on data which depends on D
        std::cout<<"Operation 1 which is " <<"D \n";
    }
    void func2()
    {
        // some operation on data which depends on D
        std::cout<<"Operation 2 which is " <<"D \n";
    }
    void execute_all(std::vector<void (Points::*)()> flist)
    {
        for (auto f: flist){
            (this->* f)();
        }
    }
};
template<int D>
using fptr = void (Points::*)();

int main()
{
    constexpr D = 2;
    Points p;
    std::set<fptr<D>> functionlist;
    functionlist.insert(&(Points<D>::func1));
    functionlist.insert(&(Points<D>::func2));
    p.execute_all(functionlist);
    return 0;
}

My intention is to group together function pointers, that I can pass to the member function in order to execute them together. In my intended code (not shown here) the "execute_all" happens in a deeply nested loop, with local arguments. I tried to run the above, even without a template class, but even that won't compile: invalid use of non-static member function ‘void Points::func1()’ Please help by pointing me to the issues with my code, and possibly providing a corrected version, that executes all functions func1 and func2 as intented.

2

There are 2 best solutions below

0
Ted Lyngmo On BEST ANSWER

Your fptr needs to use D to say to what Points member functions the pointer is actually a pointer type for.

template <int D>
using fptr = void (Points<D>::*)();

You are also mixing container types. You can't assign a set to a vector.

Fixed:

#include <iostream>
#include <vector>

template <int D>
class Points {
public:
    std::vector<int> data;

    void func1() {
        // some operation on data which depends on D
        std::cout << "Operation 1 which is " << D << "D\n";
    }

    void func2() {
        // some operation on data which depends on D
        std::cout << "Operation 2 which is " << D << "D\n";
    }

    void execute_all(const std::vector<void (Points::*)()>& flist) {
        for (auto f : flist) {
            (this->*f)();
        }
    }
};

template <int D>
using fptr = void (Points<D>::*)();

int main() {
    constexpr int D = 2;                // int was missing here
    Points<D> p;                        // <D> was missing here
    std::vector<fptr<D>> functionlist;  // was a set
    functionlist.push_back(&Points<D>::func1);
    functionlist.push_back(&Points<D>::func2);
    p.execute_all(functionlist);
}

Demo

0
Onepower On
#include <iostream>
#include <set>
#include <functional>

// Sample template class
template <typename T>
class MyClass {
public:
// Example member function
void foo(T value) {
    std::cout << "foo: " << value << std::endl;
}
};

// Function that accepts a set of member function pointers
template <typename T>
void processMemberFunctionPointers(const std::set<void (MyClass<T>::*)(T)>& 
functionPointers, T value) {
MyClass<T> obj;

// Invoke each member function pointer in the set
for (auto functionPointer : functionPointers) {
    // Call the member function using the object
    (obj.*functionPointer)(value);
}
}

int main() {
// Create a set of member function pointers
std::set<void (MyClass<int>::*)(int)> functionPointers;

// Add member function pointers to the set
functionPointers.insert(&MyClass<int>::foo);

// Process the member function pointers
processMemberFunctionPointers(functionPointers, 42);

return 0;
}

Now, In this example, we have a template class MyClass with a member function foo. The processMemberFunctionPointers function accepts a set of member function pointers as its first parameter. It takes an additional parameter value which is passed to each member function during invocation.

In the main function, we create a set functionPointers to store the member function pointers of MyClass's member functions. We add a member function pointer &MyClass::foo to the set.

Finally, we call processMemberFunctionPointers with the set of member function pointers and a value of 42. The function iterates over each member function pointer in the set and invokes it on an instance of MyClass.