为什么命名枚举值“ IN”会导致语法错误?

时间:2019-02-13 01:02:47

标签: c++ enums keyword

我有一个带有枚举长度单位的类。

class LengthUnit
{
public:
    enum Value
    {
        IN,
        CM,
        FT
    };
    static double convert(double value, Value from, Value to){
        if (from == to) return value;
        return value * getScale(from)/getScale(to);
    }
    constexpr LengthUnit(Value value) : value(value) {}

    bool operator==(LengthUnit lUnit) const { return value == lUnit.value; }
    bool operator!=(LengthUnit lUnit) const { return value != lUnit.value; }

private:
    static double getScale(Value value){
        switch (value){
        case IN: return 2.54; // 1 in = 2.54 cm
        case FT: return 30.48; // 1 ft = 30.48 cm
        case CM: return 1;
        default:
            throw QException();
        }
    }
    Value value;
};

在第6行检测到错误。

error: expected identifier before ',' token
         IN,
           ^

如果我将变量的名称从IN更改为INCHES,错误就会消失。

是什么导致此错误?据我所知,IN不是C ++或Qt的关键字,那么为什么名称会引起问题?

1 个答案:

答案 0 :(得分:2)

您尚未指定要包含的其他头文件,因此实际上不可能给出任何明确的答案。

但是,您可以做一些事情来解决名称冲突:

  • 由于显然有其他内容正在定义IN预处理程序宏,因此您可以执行以下操作:#define IN whatever之后的 所有#include来查看是否您的编译器将生成一条错误消息,说明定义它的其他位置。

  • 如果这不起作用,则可以让编译器生成经过预处理的输出(通常通过诸如-E之类的命令行选项)。然后,您可以检查它以查看被IN取代了什么,这可能会为您提供线索来源。

  • 在源文件(.cpp.cc中,您可以在所有#undef IN之后添加#include,以取消定义较早的实例,因为您大概是不需要较早的定义。 (但是,不要在头文件中执行此操作。这样做可能会引起将来的问题。)

  • 只需重命名常量即可。正如我在评论中提到的那样,应将全大写名称用于预处理器宏(并且仅用于 ),以避免名称冲突。不幸的是,这种做法在以全大写形式命名 constants 时被破坏了,但是我认为为预处理器宏设置一个单独的命名空间更加有用。