对命名空间内重载运算符的未定义引用



我在使用命名空间内部声明的重载运算符时遇到问题。

设置如下:

classa.h

#ifndef CLASSA_H
#define CLASSA_H
namespace ns1 {
class ClassA {
public:
ClassA();
enum class MyEnum : unsigned {
VAL_A = 0,
VAL_B = 1,
VAL_C = 2,
VAL_D = 4,
VAL_E = 8
};
};
// Declaration of overloaded operator
ClassA::MyEnum operator|(ClassA::MyEnum const &lhs, ClassA::MyEnum const &rhs);
} // namespace ns1
#endif // CLASSA_H

classa.cpp

#include "classa.h"
using ns1::ClassA;
ClassA::ClassA() {}
// Definition of overloaded operator
ClassA::MyEnum operator|(ClassA::MyEnum const &lhs, ClassA::MyEnum const &rhs) {
return static_cast<ClassA::MyEnum>(static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
};

main.cpp

#include "classa.h"
#include <iostream>
using ns1::ClassA;
int main() {
auto temp{ClassA::MyEnum::VAL_A | ClassA::MyEnum::VAL_B};
std::cout << (unsigned)temp << std::endl;
return 0;
}

编译器生成:

error: undefined reference to `ns1::operator|(ns1::ClassA::MyEnum const&, ns1::ClassA::MyEnum const&)'

如何在程序中使用重载运算符的定义?

您需要声明的同一命名空间中定义运算符,否则您有两个不同的、不相关的运算符(其中一个未定义,另一个仅在classa.cpp中定义(。

只需将整个实现封装在namespace ns1块中即可:

classa.cpp

#include "classa.h"
namespace ns1 {
ClassA::ClassA() {}
// Definition of overloaded operator
ClassA::MyEnum operator|(ClassA::MyEnum const &lhs, ClassA::MyEnum const &rhs) {
return static_cast<ClassA::MyEnum>(static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
};
}

using ns1::ClassA不能达到预期效果。它只将ns1::ClassA id传播到全局命名空间,但不影响其后面的定义。operator|应该在ns1作用域中定义。

namespace ns1 {
// Definition of overloaded operator
ClassA::MyEnum operator|(ClassA::MyEnum const &lhs, ClassA::MyEnum const &rhs) {
return static_cast<ClassA::MyEnum>(static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
};
}

最新更新