为什么在使用 std::pair 作为 std::unordered_map 键时需要非成员 == 运算符重载

问题描述 投票:0回答:1

在下面的例子中,我重载了

uint8_t
bool
的转换函数。并使用一对带有
boost::hash
的地图键。 之前有一个错误
ambiguity in conversion of 'const Mem' to 'float'
(不知道为什么它要求
Mem -> float
转换)所以我决定为
==
运算符添加一个重载。如果我只为
==
运算符实现成员运算符重载,这将在 clang++ 中产生编译错误。

In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/iostream:39:
In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/ostream:38:
In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/ios:40:
In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/bits/char_traits.h:39:
In file included from /opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/bits/stl_algobase.h:64:
/opt/compiler-explorer/gcc-11.2.0/lib/gcc/x86_64-linux-gnu/11.2.0/../../../../include/c++/11.2.0/bits/stl_pair.h:467:51: error: use of overloaded operator '==' is ambiguous (with operand types 'const Mem' and 'const Mem')
    { return __x.first == __y.first && __x.second == __y.second; }

为什么我需要

==
的非成员重载,因为
__x
__y
是相同的类型并且可以得到成员运算符的支持。 示例运行

#include <iostream>
#include <cstdint>
#include <unordered_map>
#include <string>

#include <boost/functional/hash.hpp>

struct Mem {
    bool inv : 1;
    uint8_t bit : 3;

    Mem(bool v = false, uint8_t bs = 0) : inv(v), bit(bs) {}

    operator uint8_t() const
    {
        return (bit << 1 | inv);
    }
    
    operator bool() const
    {
        return inv;
    }
    
    // not working for member overloading
    bool operator==(const Mem& other) 
    { 
        return inv == other.inv;
    }

};

// only work for non-member overload
// inline bool operator==(const Mem& lhs, const Mem& rhs) 
// { 
//     return lhs.inv == rhs.inv;
// }

inline std::size_t hash_value(const Mem& mem)
{
    return mem.bit;
}


int main()
{
    std::unordered_map<std::pair<std::string, Mem>, std::string, 
                       boost::hash<std::pair<std::string, Mem>>> map {};

    auto i = Mem();
    std::string k = "T";

    auto p = map.find({k, i});
     
    return 0;
}
c++ operator-overloading unordered-map std-pair ambiguity
1个回答
1
投票

您的成员

operator==
需要声明为
const
(就像您的其他成员运营商一样),例如:

bool operator==(const Mem& other) const
                                   ^^

没有它,当

left-hand
操作数不是operator==对象时,成员
const Mem
不能被使用。您的非成员
operator==
可以同时用于
Mem
const Mem
对象,因为它的
lhs
参数需要一个
const Mem&
对象引用。

© www.soinside.com 2019 - 2024. All rights reserved.