【问题标题】:Map of unique pointers, .at() with a raw pointer唯一指针映射,带有原始指针的 .at()
【发布时间】:2019-10-03 10:57:52
【问题描述】:

假设我有一张地图:

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

显然,这不起作用,因为我们地图的键值是唯一的 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() 函数。

【问题讨论】:

  • 很少需要使用指针(智能与否)作为键,而且通常是错误的。如果您有两个指针指向两个不同的对象实例,但对象实例在其他方面是“相等的”,那么它们作为键仍然是不同的(因为键是指针,而不是它们指向的对象)。跨度>
  • @Someprogrammerdude 这里有两个指针指向 same 对象
  • 为什么您认为您需要将密钥设为std::unique_ptr&lt;SomeType&gt; 而不仅仅是SomeType
  • 我正在创建的网络程序中使用这样的地图。该映射存储一个 TCP 套接字对象作为其键,另一个包含其他信息(例如 IP 地址)的对象作为其映射值。既然你提到了它,我实际上没有看到 SomeType 成为唯一指针的原因。我想我这样做是因为映射值确实必须是唯一的指针,因为其他原因。感谢您指出这一点。
  • 虽然仍然认为@Caleth 的解决方案是最好的,但您可以使用 unique_ptr 和其他类定义您的结构,并使用 (或 int 或其他)的映射

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


【解决方案1】:

在 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;
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 2018-08-26
  • 1970-01-01
  • 2017-06-17
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
相关资源
最近更新 更多