C++ 如何在一个交换机中实现多个情况下的一些排他语句和一些公共语句?

C++ 如何在一个交换机中实现多个情况下的一些排他语句和一些公共语句?,c++,c,switch-statement,goto,C++,C,Switch Statement,Goto,我有一个switch语句,其中每个案例都有唯一的代码,还有一些代码在除了默认标签之外的所有案例之间共享。 是否有一种在不同的案例标签之间共享命令的好方法 编辑:代码示例 switch (c) { case '+': command.type = ADD; commands.push_back(command); break; case '-': command.type = SUB; commands

我有一个
switch
语句,其中每个案例都有唯一的代码,还有一些代码在除了默认标签之外的所有案例之间共享。 是否有一种在不同的案例标签之间共享命令的好方法

编辑:代码示例

switch (c)
{
    case '+':
        command.type = ADD;
        commands.push_back(command);
        break;
    case '-':
        command.type = SUB;
        commands.push_back(command);
        break;
    case '>':
        command.type = INC;
        commands.push_back(command);
        break;
    case '<':
        command.type = DEC;
        commands.push_back(command);
        break;
    case '.':
        command.type = PUT;
        commands.push_back(command);
        break;
    case ',':
        command.type = GET;
        commands.push_back(command);
        break;
    default: break;
开关(c)
{
格“+”:
command.type=ADD;
命令。推回(命令);
打破
案例'-':
command.type=SUB;
命令。推回(命令);
打破
案例“>”:
command.type=INC;
命令。推回(命令);
打破
案例'
  • 将标志设置为true
  • 在开关的默认情况下,将标志设置为false
  • 如果标志为true,则运行公共代码
如下所示:

bool MyPushBackFlag = true;
switch (c)
{
    case '+':
        command.type = ADD;
        break;
    case '-':
        command.type = SUB;
        break;
    case '>':
        command.type = INC;
        break;
    case '<':
        command.type = DEC;
        break;
    case '.':
        command.type = PUT;
        break;
    case ',':
        command.type = GET;
        break;
    default: MyPushBackFlag = false; break;
}

if (MyPushBackFlag)
     commands.push_back(command);
bool MyPushBackFlag=true;
开关(c)
{
格“+”:
command.type=ADD;
打破
案例'-':
command.type=SUB;
打破
案例“>”:
command.type=INC;
打破

case'将
std::map
char
映射到
command.type
是什么类型。
让我们称之为
命令\u表

然后:

我有一个switch语句,其中每个case都有唯一的代码,还有一些代码在除了默认标签之外的所有case之间共享

对于您的特定示例案例,不同案例之间的唯一区别在于数据,而不是执行,映射可能更合适(请参阅)

通常,如果映射不合适(即,当代码路径在执行过程中不同时),可以使用这种很少使用的原始控制结构,
goto

switch( c )
{
    case '+': command.type = ADD; break;
    case '-': command.type = SUB; break;
    case '>': command.type = INC; break;
    case '<': command.type = DEC; break;
    case '.': command.type = PUT; break;
    case ',': command.type = GET; break;
    default:
        goto no_match; // or return from function if appropriate
}
commands.push_back( command );
no_match:
//...
开关(c)
{
案例“+”:command.type=ADD;break;
案例'-':command.type=SUB;break;
案例“>”:command.type=INC;break;

案例'有时重构代码只会增加复杂性…:)

#包括
#包括
#包括
枚举命令类型{
加、分、公司、十二月、卖出、卖出
};
结构命令{
命令类型;
};
std::矢量命令;
使用mapping=std::pair;
模板
bool调度(T&T、Iter优先、Iter最后、Func&f){
auto i=std::find_if(first,last,[&t](auto&&pair){return std::get(pair)==t;});
如果(i==最后一个){
返回false;
}
f(std::get(*i));
返回true;
}
模板
布尔分派(字符t、标准::数组常量和范围、函数和函数){
返回分派(t,range.begin(),range.end(),std::forward(f));
}
bool my_开关(字符c){
返回调度(c,
std::数组{{
{'+',ADD},
{'-',SUB},
{'>',INC},

{'我们可以在不实际使用它的情况下实现
goto
的效果

#define GOTO_END(...) { __VA_ARGS__; } if(false)
#define END {}
switch(c)
{
  case '+': GOTO_END(command.type = ADD)
  case '-': GOTO_END(command.type = SUB) // if `c == '-'` then jump to END
  case '>': GOTO_END(command.type = INC)
  case '<': GOTO_END(command.type = DEC)
  case '.': GOTO_END(command.type = PUT)
  case ',': GOTO_END(command.type = GET)
            END // <--- must not be forgotten
            commands.push_back(command);
  default:  break;        
}
\define GOTO_END(…){{如果(false)
#定义结束{}
开关(c)
{
案例“+”:转到结尾(command.type=ADD)
case'-':GOTO_END(command.type=SUB)//如果'c='-','则跳转到END
案例“>”:转到结尾(command.type=INC)

案例'您可以将代码重构为函数。您可以共享代码示例吗?如果所有案例都共享,请将其放在前面(或后面)switch.switch cases已经失败了,如果您想对每个switch case执行相同的语句,请显示您的代码!将switch语句更改为如下内容:
return\u type func(container&cmd,const type option/*ADD,SUB,etc./)
如果您有映射,则不需要开关“让我们调用它
命令”
或者让我们称之为与已定义的名为
commands
的向量不冲突的东西。在这种情况下,肯定会更干净、更短
if(flag==true)
我讨厌这样:(@Slava对我们来说,很明显
if(MyPushBackFlag)
可以工作,但对于OP:(@Slava你讨厌它并不意味着它是坏的。@KyleKhalaf不必要的详细代码是坏的,而
if(pointer!=nullptr)
代替
if(pointer)
可以增加可读性,相比之下
true
内部
if
是无用的。你可以编写
if((flag==true)=true)
同样,为什么不给
true
添加更多的比较呢?@Slava这只是你的偏好。程序员在任何编程语言中看到
if(flag==true)
时,都会被忽略。我的偏好是,逻辑比语法的实际操作经验更好。我会在语法之前教我的孩子逻辑。还有(学生)需要在这里学习一些逻辑@不管是谁投了反对票,你是如何发现答案没有帮助的?你有改进的建议吗?我没有投反对票,但在阅读了你的答案后,我想到的第一件事是:。虽然解决方案会起作用,但它远不是惯用的,涉及到在大多数人身上使用低于底部的语言功能les列表。我只是看不到任何价值。在这种情况下使用
goto
比其他方法更简单、更干净、更高效。但我们宁愿跳过荒谬的圈套来避免它,因为我们太害怕它了?
switch( c )
{
    case '+': command.type = ADD; break;
    case '-': command.type = SUB; break;
    case '>': command.type = INC; break;
    case '<': command.type = DEC; break;
    case '.': command.type = PUT; break;
    case ',': command.type = GET; break;
    default:
        goto no_match; // or return from function if appropriate
}
commands.push_back( command );
no_match:
//...
#include <vector>
#include <array>
#include <iostream>

enum CommandType {
    ADD, SUB, INC, DEC, PUT, GET
};

struct Command {
    CommandType type;
};

std::vector<Command> commands;

using mapping = std::pair<char, CommandType>;

template<class T, class Iter, class Func>
bool dispatch(T &&t, Iter first, Iter last, Func &&f) {
    auto i = std::find_if(first, last, [&t](auto &&pair) { return std::get<0>(pair) == t; });
    if (i == last) {
        return false;
    }
    f(std::get<1>(*i));
    return true;
}

template<class T, std::size_t N, class Func>
bool dispatch(char t, std::array<mapping, N> const &range, Func &&f) {
    return dispatch(t, range.begin(), range.end(), std::forward<Func>(f));
}

bool my_switch(char c) {

    return dispatch(c,
                    std::array<mapping, 6> {{
                                                    {'+', ADD},
                                                    {'-', SUB},
                                                    {'>', INC},
                                                    {'<', DEC},
                                                    {'.', PUT},
                                                    {',', GET}
                                            }}, [](auto type) {
                Command command{};
                command.type = type;
                commands.push_back(command);
                std::cout << "dispatched: " << command.type << std::endl;
            })
           or [](char c) { 
        std::cout << "invalid option " << c << std::endl;
        return false;
    }(c);
}


int main() {
    my_switch('+');
    my_switch('<');
    my_switch('U');
}
#define GOTO_END(...) { __VA_ARGS__; } if(false)
#define END {}
switch(c)
{
  case '+': GOTO_END(command.type = ADD)
  case '-': GOTO_END(command.type = SUB) // if `c == '-'` then jump to END
  case '>': GOTO_END(command.type = INC)
  case '<': GOTO_END(command.type = DEC)
  case '.': GOTO_END(command.type = PUT)
  case ',': GOTO_END(command.type = GET)
            END // <--- must not be forgotten
            commands.push_back(command);
  default:  break;        
}