比较 unique_ptr 的地图
Compare maps of unique_ptr
是否可以比较包含 std::unique_ptr
的两个地图?
在我的具体情况下,我想比较两个包含 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);
}
很明显,当我运行上面的测试(使用Google测试)时,测试会失败,因为比较的是地址,而不是值(为此提供了 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);
}
是否可以比较包含 std::unique_ptr
的两个地图?
在我的具体情况下,我想比较两个包含 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);
}
很明显,当我运行上面的测试(使用Google测试)时,测试会失败,因为比较的是地址,而不是值(为此提供了 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);
}