有没有一种方法可以拥有一个检查2个参数的开关?

3

我正在进行我的学校项目,想知道是否可以通过替换以下内容使我的代码更加简洁:

switch (screen) {
    case 0:
    switch (language) {
        case 0:
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
        case 1:
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;

    }
    break;
}

通过类似于这样的方式:

switch (screen)(language) {
    case 0 0:
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
    case 0 1:
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;

    }

在C ++中是否有像这样的结构?我尝试通过谷歌搜索,但无论措辞如何,都找不到任何相关内容。


2
不行,除非你想使用带有 &&if 语句。如果存在一系列允许的值,你可以尝试进行一些位移操作。但是这会使代码难以理解。 - ChrisMM
你可以使用 unordered_map<pair<size_t,size_t>,callback_t>,其中 callback_t 可以是 std::function<void(void)> 或类似的东西。 - Quimby
对于与语言无关的消息,我建议将它们存储在每种语言的一个大表中,并使用枚举进行索引,例如 english_msgs[Msg::Main_menu] - Quimby
1
C++中有关于模式匹配的提案...如果被接受,它将允许像inspect (screen, language) {when {0, 0}: /*..*/ when {1, 0} /*..*/}这样的语法。 - Jarod42
3个回答

3

我不建议在这种情况下使用switch - 有比使用switch更好的方法来进行本地化或菜单操作 - 而代码应该只做一件事,但是要将两个值合并成一个可以使用按位操作符,然后在case中使用移动整个nibbles的十六进制字面量:

switch ((screen << 4) | language) {
    case 0x00:
        std::cout << "1 - Start new game" << std::endl;
        std::cout << "2 - Load save" << std::endl;
        std::cout << "2 - Hall of fame" << std::endl;
        std::cout << "3 - Select language" << std::endl;
        std::cout << "h - Help" << std::endl;
        break;
    case 0x01:
        std::cout << "1 - Zacznij nową grę" << std::endl;
        std::cout << "2 - Wczytaj grę" << std::endl;
        std::cout << "2 - sala sławy" << std::endl;
        std::cout << "3 - wybierz język" << std::endl;
        std::cout << "h - pomoc" << std::endl;
        break;
    case 0x10:
        // screen 1 language 0
        break;
    case 0x11:
        // screen 1 language 1
        break;

    }
    break;
}

我不会在应用程序中使用这个,但已经将其用于低级别的任务,例如将多个旋转编码器传感器位和之前的状态组合起来以确定旋转方向。


@Fareanor,你需要移动足够的位数,以便你要将屏幕值放入的所有位都是空白的,不会产生干扰。如果你有255种语言,那么你就要移动8位,以此类推。 - Pete Kirkham
@PeteKirkham 是的,你说得对,这就是为什么我删除了我的评论^^ - Fareanor
1
@Fareanor -- 目前,这个问题是一个小时前提出的。现在接受答案还为时过早。接受会阻止其他人回答,并可能意味着最好的答案永远不会被发布。 - Pete Becker

3
只要您可以从输入参数编写一个返回整数类型的constexpr函数,就可以在多个选项中进行切换。
constexpr int screen_and_language(int screen, int language) {
    return (screen << 4) | language;
}

switch screen_and_language(screen, language) {
    case screen_and_language(0, 0):
            std::cout << "1 - Start new game" << std::endl;
            std::cout << "2 - Load save" << std::endl;
            std::cout << "2 - Hall of fame" << std::endl;
            std::cout << "3 - Select language" << std::endl;
            std::cout << "h - Help" << std::endl;
            break;
    case screen_and_language(0, 1):
            std::cout << "1 - Zacznij nową grę" << std::endl;
            std::cout << "2 - Wczytaj grę" << std::endl;
            std::cout << "2 - sala sławy" << std::endl;
            std::cout << "3 - wybierz język" << std::endl;
            std::cout << "h - pomoc" << std::endl;
            break;
}

从未见过这个。非常酷。 - bolov

2

虽然不是直接使用,但您可以使用单个变量来保存所需的所有语义。

例如:

含义
0 屏幕==0 && 语言==0
1 屏幕==0 && 语言==1
2 屏幕==1 && 语言==0
3 屏幕==1 && 语言==1

当然,您也可以使用枚举类型使其更明确。

这将变成:

enum MenuSettings {SL_00, SL_01, SL_10, SL_11};
含义
SL_00 screen==0 && language==0
SL_01 screen==0 && language==1
SL_10 screen==1 && language==0
SL_11 screen==1 && language==1

这种解决方法的缺点是,如果你需要处理很多语言或/和屏幕,enum会变得非常长。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接