我试图将一些类型安全标志放入几个相关的类中(不仅仅是我在这里使用的两个类),我目前在每个类中使用enum TypeFlags
。我想定义一个运算符|在每个枚举上。我可以通过为operator|
,KeyEvent::TypeFlags
等每个单独的MouseEvent::TypeFlags
函数执行此操作,或者,如下所示,通过定义模板化函数:
#include <iostream>
class KeyEvent
{
public: enum TypeFlags {KEYFLAG1=1, KEYFLAG2=2, KEYFLAG3=4};
};
class MouseButtonEvent
{
public: enum TypeFlags {MOUSEFLAG1=1, MOUSEFLAG2=2, MOUSEFLAG3=4};
};
template<typename EC> EC operator|(EC a, EC b)
{
return static_cast<EC>(static_cast<int>(a)|static_cast<int>(b));
}
void DoSomething(KeyEvent::TypeFlags t) {std::cout << t << std::endl;}
int main()
{
DoSomething(KeyEvent::KEYFLAG1 | KeyEvent::KEYFLAG2);
return 0;
}
上面的代码有效,但这个模板operator|
并不理想,因为它可以对任何事情进行操作。我想限制它只在Class :: TypeFlags枚举上运行。我尝试用以下代码替换上面的模板:
template<typename EC> typename EC::TypeFlags operator|(typename EC::TypeFlags a, typename EC::TypeFlags b)
{
return static_cast<typename EC::TypeFlags>(static_cast<int>(a)|static_cast<int>(b));
}
但是,在编译时,新的模板operator|
不被称为[T.C.在评论中解释了为什么]。 (相反,当两个标志一起进行OR运算时,它们会隐式转换为int
,并调用int
operator|
版本。结果int
则无法通过到DoSomething
。)
有没有办法编写模板化的operator|
,以便它只对我的TypeFlags
枚举起作用?如果它存在,我想要一个解决方案,a)不允许在不同类之间混合标志,并且b)如果我添加或删除带有标志的Event类,则不需要修改在它。