我有几个类似于以下的嵌套枚举。我希望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
的主体内?
答案 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; }
使用V1
或V2
不合格将是非法的。
答案 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); }