带有原始指针的唯一指针.at()的映射

时间:2019-05-16 08:14:33

标签: c++ dictionary pointers std unique-ptr

说我有一张地图:

std::map<std::unique_ptr<SomeType>, SomeOtherType> map;

显然,这是行不通的,因为我们地图的键值是唯一的ptr,而不是原始的ptr:

//a pointer from somewhere else in the code
SomeType* p = ...;
auto result {map.at(p)};

相反,可以使用std :: unique_ptr.get()做类似的事情

SomeType* p = ...;
for(auto& entry : map) {
    if(entry.first.get() == p) {
        //do whatever
    }
}

但这是一种非常丑陋且可能效率低下的方法。我的问题很简单,在这种情况下是否可以使用.at()函数。

1 个答案:

答案 0 :(得分:6)

在C ++ 14中,您可以提供一个透明的比较器

template<typename T>
struct PtrCompare
{
    std::less<T*> less;
    using is_transparent = void;
    bool operator()(T* lhs, const std::unique_ptr<T> & rhs) const { return less(lhs, rhs.get()); }
    bool operator()(const std::unique_ptr<T> & lhs, T* rhs) const { return less(lhs.get(), rhs); }
    bool operator()(const std::unique_ptr<T> & lhs, const std::unique_ptr<T> & rhs) const { return less(lhs.get(), rhs.get()); }
}

std::map<std::unique_ptr<SomeType>, SomeOtherType, PtrCompare<SomeType>> map;

这对at并没有帮助,但确实允许您根据您可以比较的任何内容来find

SomeType* p = ...;
if (auto it = map.find(p))
{
    // use it->second
}
else
{
    throw std::out_of_range;
}