Reputation: 3776
I'm creating a console application in c++ with a lot of menus and sub-menus. The way I display my menu is through a do-while loop. I created a function to display the menu loop with three parameters - first being an integer that relates to how many options are in the menu, the second being a function displaying the menu and the third being another function which performs the selection inputed by the user.
class Menu {
public:
void displayInitialMenu(){
system("cls");
string menu = "\n\t\tXXXXXXXXX"\
"\n\n Please select from the following:"\
"\n\n 1. XXXXXXX"\
"\n\n 2. XXXXXXX"\
"\n\n 3. Exit\n";
cout << menu << endl;
}
static bool checkOption (int option, int lower, int upper){
if ((option < lower) || (option > upper)){
return false;
} else {
return true;
}
}
static int readOption(int lower, int upper){
int option = 0;
bool validMenuOption = false;
do{
std::cin >> option;
validMenuOption = checkOption(option, lower, upper);
if (!validMenuOption){
std::cout << "\nError: Input must be between " << lower;
std::cout << " and " << upper << "\n" << std::endl;
}
} while (!validMenuOption);
return option;
}
};
Menu menu;
void menuLoop(int numberOfOptions, void (*displayMenu)(), void (*switchStatement)()){
int menuOption = numberOfOptions;
do {
(*displayMenu)();
menuOption = menu.readOption(1, numberOfOptions);
(*switchStatement)();
} while (menuOption != numberOfOptions);
}
static void performSelectionInitialMenu(int option){
switch (option){
case 1:
break;
case 2:
break;
case 3:
break;
default:
break;
}
}
int main()
{
/*
int menuOption = 3;
do {
menu.displayInitialMenu();
menuOption = menu.readOption(1, 3);
performSelectionInitialMenu(menuOption);
} while (menuOption != 3);
*/
menuLoop(3, &menu.displayInitialMenu(), &performSelectionInitialMenu(3));
return 0;
}
The error I'm receiving is "error C2102: '&' requires l-value". I'm somewhat new to programming and this is the first time I'm passing through a function as a parameter. I'm making this function to eliminate code that I've commented out. Can anyone point to where I'm going wrong and a possible solution. If not, I'll just use duplicate code for each menu which I know is bad programming practice.
Upvotes: 2
Views: 7060
Reputation: 121
menuLoop(3, &menu.displayInitialMenu(), &performSelectionInitialMenu(3));
It is not what you are trying to achieve. First, you cant take adress of things, which are not variable. So, you will have to do following :
you have to do something like :
menuLoop(3, menu.displayInitialMenu, performSelectionInitialMenu, 3); Please note you will have to pass three as an extra parameter.
and also change the signature of menuLoop accordingly.
Upvotes: 0
Reputation: 4708
First of all, as soon as you put the parantheses after the name of a function, you are not talking about the function itself anymore. i.e for free functions (functions that are not class members) func
refers to the address of the function func
, whereas func()
refers to whatever is returned from that function.
You have another problem though. You're trying to pass a non-static class member function as a free function. This is not legal in c++, since non-static member functions have a hidden argument, namely, the object that it's invoked on. Although in theory object.memberfunc
could refer to a delegate that, when invoked, calls memberfunc
on object
, it doesn't in C++. As is customary in C++, there are approximately one billion ways to obtain this effect with a billion trade-offs in various criteria.
I think, for you, the easiest is to use boost.bind. So, what you're trying to do would look like:
#include<boost/bind.hpp>
using namespace boost;
...
template <class Functional>
void menuLoop(int numberOfOptions, Funcional displayMenu, void (*switchStatement)()){
...
menuLoop(3, bind(Menu::displayInitialMenu,menu), &performSelectionInitialMenu(3));
...
Upvotes: 0
Reputation: 1024
You are trying to take the addresses of values, returned by the functions displayInitialMenu
and performSelectionInitialMenu
, but both of these functions return nothing (void
). Remove the &
in front of both calls to fix this particular problem.
Upvotes: 2
Reputation: 62459
Normally you would only call it like this:
menuLoop(3, menu.displayInitialMenu, performSelectionInitialMenu);
just name, no parameters.
However, performSelectionInitialMenu
is:
static void performSelectionInitialMenu(int option)
So it does not match the signature of the pointer:
void (*switchStatement)()
which means they are not compatible.
Upvotes: 2