【问题标题】:std::map in tempate class <T> with key of <T>模板类 <T> 中的 std::map,键为 <T>
【发布时间】:2012-09-09 16:36:53
【问题描述】:

我有自定义二叉树类,它保存模板类型T 的值(它可以是值或指针)。每个值都用数字封装(这个数字用于在树中搜索)。我想在我的树类中有一个std::map,以便快速 O(1) 访问没有数字的对象。

template <typename T>
stuct BSTNode 
{
  T value;
  int searchValue;
}

template <typename T>
class BST 
{
  BSTNode<T> * root;
  std::map<T, BSTNode<T>> cache;
  //... etc.
}

示例:我将类实例 a 插入到值 n 下的树中。现在我想获取与此a 关联的节点。我无法搜索树,因为我没有n。所以我想使用a,并从std::map 得到node = map[a]。现在我可以做node-&gt;n

我怎样才能做到这一点?我可以覆盖std::map的比较方法:

bool operator()(const void * s1, const void * s2) const

但它不能同时用于值和指针:不能将参数1从const double转换为const void *

【问题讨论】:

  • std::map 提供 O(log N) 访问权限,而不是 O(1)。
  • 我知道...我也可以使用其他实现。而且它仍然比迭代整个 BST 和比较 O(N) 中的每个节点要快
  • a的类型是什么?你只是说它是一个“类实例”。如果它是T 的一个实例,那么你为什么需要覆盖任何东西? T 可以比较(在这种情况下地图将工作),或者它不能(在这种情况下你正在做的事情是不可能的 - 你的模板必须要么要求 T 是可比较的,要么采用像map 这样的比较器并将该比较器传递给它的map 数据成员)。
  • 示例:T 是 int... 完全没问题,只是比较值。如果 T 是 MyClass *,那么我想比较指针地址,而不是类的实际内容。因此,MyClass 中的重载运算符不适用于我的目的。
  • @Martin Perry: std::map 使用 std::less 作为其默认比较器。 std::less&lt;MyClass*&gt; 确实比较地址,而不是指向的对象。所以它会做你想做的事。

标签: c++ templates stdmap


【解决方案1】:

制作一个有特征的比较器:

template <typename T>
struct NodeComp
{
    bool operator<(T const & lhs, T const & rhs) const
    {
        return lhs < rhs;
    }
};

template <typename U>
struct NodeComp<U *>
{
    bool operator<(U * lhs, U * rhs) const
    {
        return *lhs < *rhs;
    }
};

现在您的地图可以这样定义:

template <typename T>
class BST 
{
    BSTNode<T> * root;
    std::map<T, BSTNode<T>, NodeComp<T>> cache;
}

【讨论】:

  • 它不起作用...比较器写在 BSTNode 上,而 key 只是 T...还是我弄错了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
相关资源
最近更新 更多