C ++错误C2102:'&'需要l值

时间:2012-05-17 10:15:26

标签: c++ lvalue

我正在用c ++创建一个带有很多菜单和子菜单的控制台应用程序。我显示菜单的方式是通过do-while循环。我创建了一个函数来显示带有三个参数的菜单循环 - 第一个是与菜单中有多少个选项有关的整数,第二个是显示菜单的函数,第三个是执行用户输入的选择的另一个函数

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;
}

我收到的错误是“错误C2102:'&amp;'要求l值“。我对编程有些新意,这是我第一次将函数作为参数传递。我正在使用此功能来消除我已注释掉的代码。任何人都可以指出我出错的地方和可能的解决方案。如果没有,我将只为每个菜单使用重复的代码,我知道这是糟糕的编程习惯。

4 个答案:

答案 0 :(得分:2)

您正在尝试获取函数displayInitialMenuperformSelectionInitialMenu返回的值的地址,但这两个函数都不返回任何内容(void)。 删除两个调用前面的&以解决此特定问题。

答案 1 :(得分:2)

通常你只会这样称呼它:

menuLoop(3, menu.displayInitialMenu, performSelectionInitialMenu);

只是名字,没有参数。

但是,performSelectionInitialMenu是:

static void performSelectionInitialMenu(int option)

所以它与指针的签名不匹配:

void (*switchStatement)()

这意味着它们不兼容。

答案 2 :(得分:0)

首先,只要将parantheses放在函数名后面,就不再讨论函数本身了。即自由函数(不是类成员的函数)func指的是函数func的地址,而func()指的是从该函数返回的函数。

但你有另一个问题。您正在尝试将非静态类成员函数作为自由函数传递。这在c ++中是不合法的,因为非静态成员函数有一个隐藏的参数,即它被调用的对象。虽然理论上object.memberfunc可以引用一个委托,当被调用时,在memberfunc上调用object,但它不在C ++中。按照C ++的惯例,大约有十亿种方法可以通过各种标准进行十亿次权衡来获得这种效果。

我认为,对您而言,最简单的方法是使用boost.bind。那么,你想要做的就是:

#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));

...

答案 3 :(得分:0)

menuLoop(3,&amp; menu.displayInitialMenu(),&amp; performSelectionInitialMenu(3));

这不是你想要实现的目标。首先,你不能采取不变的东西。所以,你必须做以下事情:

  1. 删除“&amp;”。
  2. 在displayInitialMenu和performSelectionInitialMenu之后删除“()”,因为它确实意味着将调用这些函数并且返回值在当前情况下为void,将传递给menuLoop。所以,你不会得到你想要达到的目标。
  3. 你必须做类似的事情:

    menuLoop(3,menu.displayInitialMenu,performSelectionInitialMenu,3);请注意,您必须将三个作为额外参数传递。

    并相应地更改menuLoop的签名。