比较unique_ptr的映射

Compare maps of unique_ptr

本文关键字:映射 ptr unique 比较      更新时间:2023-10-16

是否有可能比较包含std::unique_ptr s的两个映射?

在我的具体情况下,我想比较两个包含std::unique_ptr元组的映射(std::tuple部分与问题无关,但我认为在手动实现最基本的操作(如比较)时,考虑使用异构类型所引起的复杂性是很重要的)。

class MyObject
{
public:
    bool operator==(const MyObject& other) const
    {
        return member1 == other.member1;
    }
    bool operator!=(const MyObject& other) const;
private:
    std::string member1 = "specific string";
};
TEST(General, CompareMapOfTuplesOfUniquePtrs)
{
    using MyType = std::map<int32_t, std::tuple<int32_t, std::unique_ptr<MyObject>>>;
    MyType map1;
    MyType map2;
    map1.insert({ 1, std::make_tuple(2, std::make_unique<MyObject>()) });
    map2.insert({ 1, std::make_tuple(2, std::make_unique<MyObject>()) });
    ASSERT_EQ(map1, map2);
}

显然,当我运行上述测试(使用GoogleTest)时,测试将失败,因为比较的是地址,而不是值(提供了operator==operator!=)。

Actual: { (1, (2, 4-byte object <B8-BF 86-01>)) }
Expected: map1
Which is: { (1, (2, 4-byte object <A0-BC 86-01>)) }
[FAILED]

我可以手动迭代每个对并取消引用每个对象,但我想知道unique_ptr是否有一个更标准化的解决方案,因为它是一个基本的构造。

我能想到的最标准的解决方案就是为元组定义自己的等式运算符:

bool operator==( const std::tuple<int32_t, std::unique_ptr<MyObject>> & a,
                 const std::tuple<int32_t, std::unique_ptr<MyObject>> & b )
{
    return std::get<0>(a) == std::get<0>(b) && *std::get<1>(a) == *std::get<1>(b);
}

这个示例可能对您来说已经足够了,除非您还想处理nullptr。如果您对其他元组使用相同的模式,那么将其模板化可能是有意义的:

template < class A, class B >
bool operator==( const std::tuple<A, std::unique_ptr<B>> & a,
                 const std::tuple<A, std::unique_ptr<B>> & b )
{
    return std::get<0>(a) == std::get<0>(b) && *std::get<1>(a) == *std::get<1>(b);
}