Home > database >  How to pass a member function to a gloabal function in cpp?
How to pass a member function to a gloabal function in cpp?

Time:09-24

Im on a Cpp beginner project. making a library system. And I wrote the following void Student::show(void) function to show student's details. Also I have written the first function to avoid repeating. I want to pass the create function to the printAtEnd function as a argument. But it gives me some errors. What I did wrong here.

// conclusion menu
template <typename R, typename A, typename C>
// R - return type
// A - argument type
// C - class type
void printAtEnd(R (C::*func)(A)){
    int i;
    cout << "Choose one of following.\n";
    cout << "\t1. go to main menu.\n";
    cout << "\t2. try again.\n";
    cout << "\t3. exit the program\n";
    cin >> i;

    switch(i){
        case 1: mainMenu(); break;
        case 2: func(); break;
        case 3: exit(0); break;
    }
}


void Student::show(void){
     system("clear");
     cout << "\tStudent details\n\n";
 
     cout << "Name: " << name << endl;
     cout << "Addmission No: " << addmission_no << endl;
     cout << "Email: " << email << endl;
     cout << "Telephone No: " << telephone_no << endl;
     cout << "Issued books: \n";
     for (string x: issued_books)
         cout << x << endl;
 
     printAtEnd<void, void, Student>(&Student::show);
}

I get following error when compiling.

library.cpp: In member function ‘void Student::show()’:
library.cpp:151:36: error: no matching function for call to ‘printAtEnd<void, void, Student>(void (Student::*)())’
  151 |     printAtEnd<void, void, Student>(&Student::show);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
library.cpp:79:6: note: candidate: ‘template<class R, class A, class C> void printAtEnd(R (C::*)(A))’
   79 | void printAtEnd(R (C::*func)(A)){
      |      ^~~~~~~~~~
library.cpp:79:6: note:   template argument deduction/substitution failed:
library.cpp: In substitution of ‘template<class R, class A, class C> void printAtEnd(R (C::*)(A)) [with R = void; A = void; C = Student]’:
library.cpp:151:36:   required from here
library.cpp:79:6: error: invalid parameter type ‘void’
library.cpp:79:6: error: in declaration ‘void printAtEnd(R (C::*)(A))’

All I want is call printAtEnd function after every other functions. So I need to pass the pointer to a function to printAtEnd function.

CodePudding user response:

Removing useless code from the question, it could be something like:

void printAtEnd(std::function<void ()> fn)
{
    fn();
}
 
void Student::show()
{
    printAtEnd([this](){ this->show(); });
}

However, the problem with your code it that it is recursive and if the user always select the option 2, you might eventually get a stack overflow if you run on some small memory device.

In a case like this one, a loop would usually be a better option.

  • Related