模板枚举运算符重载决策

时间:2014-09-12 10:38:20

标签: c++ templates enums operator-overloading

我试图将一些类型安全标志放入几个相关的类中(不仅仅是我在这里使用的两个类),我目前在每个类中使用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类,则不需要修改在它。

0 个答案:

没有答案