将C ++枚举类成员拉入全局命名空间

时间:2018-04-26 21:27:39

标签: c++ enums

是否有//Create a reference to the object var my_obj = this.my_obj; //Add an event listener this.button_1.addEventListener("click", onReset); //On Reset function handler function onReset(e){ my_obj.getBounds().height += 10; } 指令将using的成员直接导入编译单元的全局命名空间?

我们有:

enum class

这是有风险的,因为用户经常忘记enum Lexeme {....lots of names...}; bool Matches(int lookAhead, Lexeme lxm); 的第一个参数意味着"匹配"并写:

Matches

C ++编译器非常高兴将if (Matches(ADD,SUB)) ... 作为int。

所以我尝试将ADD改为Lexeme

enum class

这会捕获错误。但现在我的问题是所有使用enum class Lexeme { ...} 常量的代码都必须写出Lexeme名称:

enum class

是否有if (Matches(Lexeme::ADD,Lexeme::SUB)) ... 指令或其他技巧将所有using名称拉入当前范围?注意,大多数令牌都在一个类中使用(我认为正确限定常量是Lexeme::*)的安全机制之一。

或许更好的计划是将enum class更改为Matches或其他内容,以避免出现此问题?但我想知道C ++和C ++ XX的规则,至少。

我尝试了什么:

This是相关的,但没有解决所需的MatchesAt前缀。

我也试过像enum class这样的东西;但是唉也无济于事。

2 个答案:

答案 0 :(得分:1)

你可以使一个整数包装类不能转换为其他任何东西并从中产生一些常量。

struct Lexeme
{
   private: int m_value;

   public: explicit constexpr Lexeme(int value) noexcept
   : m_value{value}
   {}
};

inline constexpr Lexeme const ADD{1};
inline constexpr Lexeme const SUB{2};

为这个类重载一些运算符可能是个好主意,至少是相等而不是。

答案 1 :(得分:1)

另一方面,一种避免每次写Lexeme::的方法只是创建一个较短的别名:

enum class Lexeme { /* lotsa names */ };
using L = Lexeme;

if (Matches(3, L::SUB)) //...

如果只有一个或两个文件广泛使用这些值,并且其他用途稀疏,则此方法很有效。我只需要使用类似的解决方案,我有一个从XML读取东西的Parameter类。我有一个enum class ElementType { INTEGER, BOOLEAN, /* etc*/ }和一个解析基础设施。在解析器文件中,我有:

using ET = ElementType;

template<ET et>
struct parser;

// Specializations for each ElementType
template<>
struct parser<ET::INTEGER> {
    using type = int;
    int parseSingle(const string& s) // ...
}

虽然在这个文件之外我只有一些ElementType :: *常量的用法,我使用枚举类的全名。如果这成为太多的负担,没有什么能阻止我将别名变成另一个文件。