嵌套枚举上的C ++操作

时间:2012-01-03 15:36:10

标签: c++ enums nested operator-keyword

我有几个类似于以下的嵌套枚举。我希望isValid()函数定义为尽可能接近enum定义。实际代码更详细,具有多层嵌套命名空间和结构。

struct S
{
    enum E { V1, V2 };
    /* ????? */ bool isValid(E e) { return e==V1 || e==V2; }
};

template <typename Enum>
bool legalValue(Enum e)
{  
    return isValid(e);
}

是否可以在不必将isValid()放入全局命名空间的情况下使此代码正常工作?

请不要评论isValid()是否是良好做法。此问题适用于想要覆盖operator<<()以便能够有意义地传输枚举值的人。在这种情况下,operator<<()的本质是否有任何方法可以位于struct S的主体内?

4 个答案:

答案 0 :(得分:4)

不,您必须将isValid移出struct。但是enum定义可以保留在其中。

struct S
{
    enum E { V1, V2 };
};

bool isValid(S::E e) { return e == S::V1 || e == S::V2; }

template <typename Enum>
bool legalValue(Enum e)
{
    return isValid(e);
}

答案 1 :(得分:3)

无法从S找到S::E

如果S是命名空间,Koenig lookup会找到isValid,即使它不是全局命名空间的一部分,但我认为这不是你的意思。

答案 2 :(得分:1)

如果这是针对标准C ++,即对于C ++ 2011,您可以转发声明嵌套枚举:

struct S { enum E: int; };

enum S::E: int { V1, V2 };
bool isValid(S::E e) { return e == S::V1 || S::V2; }

当然,您也不需要将枚举嵌套到结构中以避免污染封闭范围:相反,您可以使用

enum class S { V1, V2 };
bool isValid(S e) { return e == S::V1 || S::V2; }

使用V1V2不合格将是非法的。

答案 3 :(得分:1)

这些可能是技术要点,但制作isValid全局的另一个选择是重载(或专门化)legalValue

struct S
{
    enum E { V1, V2 };
    static bool isValid(E e) { return e==V1 || e==V2; }
};
bool legalValue(S::E e) { return S::isValid(e); }

template <typename Enum>
bool legalValue(Enum e) { return isValid(e); }

另一个选择是让isValid成为全球朋友。虽然这与它只是一个自由的全球功能几乎没有区别。

struct S
{
    enum E { V1, V2 };
    friend bool isValid(E e) { return e==V1 || e==V2; }
};
template <typename Enum>
bool legalValue(Enum e) { return isValid(e); }