我正在尝试为命名空间中的union类重载比较运算符,以将其用作unordered_map中的键。
x.h:
#include <DirectXPackedVector.h>
namespace std
{
template<> struct hash<DirectX::PackedVector::XMUBYTEN4>
{
std::size_t operator()(DirectX::PackedVector::XMUBYTEN4 const& s) const {
std::size_t const h1(std::hash<uint8_t>()(s.x));
std::size_t const h2(std::hash<uint8_t>()(s.y));
std::size_t const h3(std::hash<uint8_t>()(s.z));
std::size_t const h4(std::hash<uint8_t>()(s.w));
return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3);
}
};
}
std::unordered_map<DirectX::PackedVector::XMUBYTEN4, unsigned int> mc_province_index;
散列工作正常,但是当我尝试像这样重载比较运算符时:
bool operator==(const DirectX::PackedVector::XMUBYTEN4 & lhs, const DirectX::PackedVector::XMUBYTEN4 & rhs) {
if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w)
return true;
return false;
}
我得到了
C2678: binary '==' : no operator found which takes a left-hand operand of type 'const DirectX::PackedVector::XMUBYTEN4' (or there is no acceptable conversion)
我尝试在命名空间
中进行namespace DirectX{
namespace PackedVector{
bool operator==(const DirectX::PackedVector::XMUBYTEN4 & lhs, const DirectX::PackedVector::XMUBYTEN4 & rhs) {
if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w)
return true;
return false;
}
}
}
但是这给了我一个LNK2005,说它已经在目标文件中定义了。
我在这里做错了什么以及如何重载此运算符?
答案 0 :(得分:2)
您应该将operator==()
定义为inline
函数(如果存在于头文件中),因为您很可能违反一个定义规则。
http://en.cppreference.com/w/cpp/language/definition [一个定义规则]
每个非内联函数或变量的唯一定义 在整个过程中需要使用odr-used(见下文) 程序(包括任何标准和用户定义的库)。该 编译器不需要诊断此违规,但行为 违反它的程序是未定义的。
对于内联函数, 每个翻译单元都需要一个定义 ODR使用。
基本上有bug类别如何违反ODR。
修复很简单:
namespace DirectX{
namespace PackedVector{
inline bool operator==(const DirectX::PackedVector::XMUBYTEN4 & lhs, const DirectX::PackedVector::XMUBYTEN4 & rhs) {
if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w)
return true;
return false;
}
}
}