Indy411
Indy411

Reputation: 3776

C++ Error C2102: '&' requires l-value

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

Answers (4)

saurabh jindal
saurabh jindal

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 :

  1. remove the "&".
  2. remove the "()", after displayInitialMenu and performSelectionInitialMenu, since it does mean that these functions will be called and the return value which is void in current case, will be passed to menuLoop. So, you wont get what you are trying to achieve.

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

enobayram
enobayram

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

irobot
irobot

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

Tudor
Tudor

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

Related Questions