【发布时间】:2021-03-09 09:42:51
【问题描述】:
我有一个枚举类 E 嵌套在类 C 中。我想把它用作位标志,所以我重载了它的运算符。
我的类C 包含函数test(),它使用了重载运算符。因为它只有两行长,所以它位于要内联的头文件中。但是,这个函数并没有调用重载的操作符,而是使用了默认的操作符。
我知道可能是因为我的运算符是在C 类之后定义的,所以C 不知道它们存在。我可以将嵌套枚举移到外面并在 C 类之前定义运算符,但我想知道,有没有办法在保留 C::E 层次结构的同时做到这一点?
main.cpp
#include "myenum.h"
int main() {
std::cout << "Should be false (main): " << ((C::E::e2 | C::E::e4) != C::E::e4) << std::endl;
C c(C::E::e2 | C::E::e4);
c.test(C::E::e4);
return 0;
}
myenum.h
#pragma once
#include <iostream>
class C {
public:
enum class E {
e2 = 2,
e4 = 4
};
const E e;
C(E e) : e(e) {}
void test(E e) {
std::cout << "Should be false (test): " << (this->e != e) << std::endl;
}
};
// Flag active
inline bool operator==(C::E lhs, C::E rhs) {
auto l = static_cast<std::underlying_type<C::E>::type>(lhs);
auto r = static_cast<std::underlying_type<C::E>::type>(rhs);
auto value = l & r;
return value == r || value == l;
}
// Flag inactive
inline bool operator!=(C::E lhs, C::E rhs) {
std::cout << "Overloaded operator call" << std::endl;
return !(lhs == rhs);
}
inline C::E operator|(C::E lhs, C::E rhs) {
return (C::E)(static_cast<std::underlying_type<C::E>::type>(lhs) | static_cast<std::underlying_type<C::E>::type>(rhs));
}
【问题讨论】:
-
您必须在自定义运算符重载后实现
test。或者,也许您可以稍后使用模板来定义运算符 -
@김선달 这其实是个好主意。我不知道允许实现和声明分开,但都在头文件中。不过,我不确定模板如何使用?
-
如果
test是inline函数,则允许。更准确地说,当myenum.h包含在多个文件中时,如果函数不是inline,则可能会出现重复错误。
标签: c++ operator-overloading header-files inner-classes