C ++:switch语句中的struct成员 [英] C++: struct member in a switch statement

查看:97
本文介绍了C ++:switch语句中的struct成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用C ++写一个微处理器仿真器,我的目标之一是使它的代码可读性强。为了实现操作码,我有一个用来表示单个处理器指令的结构,它同时包含操作码和程序计数器的前进距离。

I am writing a microprocessor emulator in C++, and one of my goals was to make it the code very readable. To implement opcodes, I have a struct which I am using to represent individual processor instructions, and it contains both the opcode and how far to advance the program counter. The idea was to group related information about each instruction.

struct instruction
{
    const int opcode; // instruction opcode
    const int op_size; // how far to advance Program Counter
};

const instruction HALT{0x76, 1};
const instruction NOP {0x00, 1};

我最初的计划是使用此结构定义所有操作码,因为我的印象是 const 优先于对C ++常量使用 #define 。另外,我将能够对操作码的所有相关属性进行干净的分组。

My original plan was to define all the opcodes using this struct, as I was under the impression that const was preferred to using #define for C++ constants. In addition, I would be able to cleanly group all related attributes of an opcode.

但是,这似乎对切换语句不起作用,正如我最初打算的那样。以下代码无法编译,Visual Studio给出错误 case expression not constant。

However, it seems that this will not work for switch statements, as I originally intended. The following code will not compile, and Visual Studio gives the error "case expression not constant".

switch (next_instruction) { // next_instruction is an int parsed from a file
    case HALT.opcode:
        // do stuff
        break;
    case NOP.opcode:
        // do stuff
        break;
    default:
        std::cout << "Unrecognized opcode" << std::endl;
            break;
    }

我还下载了最新的Visual Studio编译器(MSVC,2013年11月CTP)尝试利用C ++ 11中的 constexpr ,但是我遇到了同样的问题,并且无法编译。在这里,我将结构转换为类,并尝试利用 constexpr 来确保指令的成员可以

I've also downloaded the latest Visual Studio compiler (MSVC November 2013 CTP) to try to leverage constexpr from C++11, but I had the same problem, and it will not compile. Here I converted my struct to a class and attempted to leverage constexpr, to ensure that the members of an instruction could be used as compile-time constants.

class Instruction
{
  public:
    constexpr Instruction(int code, int size) : opcode(code), op_size(size) {}
    const int opcode; // instruction opcode
    const int op_size; // how far to advance Program Counter
};

constexpr Instruction HALT(0x76, 1);
constexpr Instruction NOP (0x00, 1);

我现在不确定要做什么,因为似乎编译器没有

I'm not really sure what to do at this point, since it appears that the compiler does not understand that the struct values are assigned as constants.

所以有什么方法可以在switch语句中使用struct成员,还是我应该切换为使用 #define ?或者,是否有更好的方法可以在保留一些组织的同时做到这一点?非常感谢您提供的任何帮助或见解,谢谢!

So is there any way to use a struct member in a switch statement, or should I just switch to using #define? Alternatively, is there a better way to do this while still retaining some organization? I'd really appreciate any help or insight you can offer, thanks!

编辑:抱歉,我应该更清楚地知道next_instruction是只是一个整数,而不是指令 struct / object

Sorry, I should have made it clearer that next_instruction is just an int, not an instruction struct/object

推荐答案

I'我们已经使用MinGW 4.8.3编译器在Qt Creator 3.1.2中测试了您的代码。
只需在每个指令定义中用constexpr替换const即可使编译器感到高兴:

I've tested your code in Qt Creator 3.1.2 with MinGW 4.8.3 compiler. Just replacing const by constexpr in each instruction definition made the compiler happy:

struct instruction
{
    const int opcode; // instruction opcode
    const int op_size; // how far to advance Program Counter
};

// Replacing "const" by "constexpr" int these two lines
constexpr instruction HALT{0x76, 1};
constexpr instruction NOP {0x00, 1};

int main() {
    int next_instruction = 0x76;
    switch (next_instruction) { // next_instruction is an int parsed from a file
        case HALT.opcode:
            // do stuff
            break;
        case NOP.opcode:
            // do stuff
            break;
        default:
            std::cout << "Unrecognized opcode" << std::endl;
                break;
        }
}

编辑以添加一些报价

C ++编程语言(第四版)谈到switch语句中的标签:

The C++ Programming Language (Fourh Edition) says about labels in switch statements:


标签中的表达式必须是整数或枚举类型的常量表达式
(9.4.2 switch语句)。

"The expression in the case labels must be a constant expression of integral or enumeration type." (9.4.2 switch Statements").

从10.4节常量表达式开始:

From Section 10.4 Constant Expressions:


C ++提供了常量的两个相关含义:

C++ offers two related meaning of "constant":


  • constexpr:在编译时求值

  • const:请勿在此范围内修改

基本上, constexpr 的作用是启用和确保
的编译时评估,而const的主要作用是指定接口中的
不变性。

Basically, constexpr’s role is to enable and ensure compile-time evaluation, whereas const’s primary role is to specify immutability in interfaces.

[…]

常量表达式中的10.4.2常量

10.4.2 const’s in Constant Expressions

[…]用常量表达式初始化的const可用于
常量表达式。 const与constexpr的不同之处在于,它可以用非常量表达式来初始化
。在那种
情况下,不能将const用作常量表达式。

[…] A const initialized with a constant expression can be used in a constant expression. A const differs from a constexpr in that it can be initialized by something that is not a constant expression; in that case, the const cannot be used as a constant expression.

switch语句中的标签需要constexpr以便求值在编译时完成。
因此,似乎 const指令HALT {0x76,1} 不能确保编译时间评估,而 constexpr指令HALT {0x076,1}

Labels in switch statements requieres constexpr so that evaluation is done at compile time. So it seems that const instruction HALT {0x76,1} does not ensure compile time evaluation while constexpr instruction HALT {0x076,1} does.

这篇关于C ++:switch语句中的struct成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆