C++ STL 错误的密钥类型

C++ STL wrong keys types

本文关键字:密钥 类型 错误 STL C++      更新时间:2023-10-16

无法理解这一点:G++编译器对以下方面很生气:

lengths.insert(pair<Deux,long>(d,one));

哪里

struct Deux {long big; long small};
map<Deux, long> lengths;
Deux d;
long one;

所以,G++说,我想念operator<。 在为struct Deux制作重载operator<后,我看到了新的有趣,但相同的错误:

map <long, Node*>ArrayOfNodes;
map <long, Node*>::iterator it;  
  for (it=ArrayOfNodes[Root]->nodes.begin();it<ArrayOfNodes[Root]->nodes.end();++it)
      cout<<it->first<<endl;

还使用了结构节点:

struct Node {
   long name;
   long guest;
   map <long,Node*>nodes;
/*bool operator<(const Node& node)const{
 if ((*this).name<node.name) return true;
 if ((*this).name>node.name) return false;
  return (*this).guest<(*this).guest;
}*/

错误是:

    no match for operator< in it < ((Path*)this)->Path::ArrayOfNodes.
 std::map<_Key, _Tp, _Compare, _Alloc>::operator[] [with _Key = long int, _Tp = Node*,
 _Compare = std::less<long int>, _Alloc = std::allocator<std::pair<const long int, Node*> >]
 (((const long int&)((const long int*)(&((Path*)this)->Path::Root))))->Node::nodes.std::map<_Key, _Tp, _Compare, _Alloc>::end 
 [with _Key = long int, _Tp = Node*, _Compare = std::less<long int>, _Alloc = std::allocator<std::pair<const long int, Node*> >]()

编译器抱怨没有Deux operator <(我猜(。键必须是与operator <可比较的类,或者您必须传递第三个模板参数来映射 - 比较器。

你看,地图以有序的方式保存其密钥。为了对它们进行排序,它需要一个谓词。默认情况下,它尝试使用operator <

试着写这样的东西:

bool operator < (Deux const & d1, Deux const & d2)
{
   if(d1.big > d2.big)
      return false;
   if(d1.big < d2.big)
     return true;
   return d1.small < d2.small;  
}

您没有提到错误消息。总是发布它!

因此,我需要将我的帖子分为两个不同的部分。

缺少声明。

`error: 'Deux' was not declared in this scope`

那是因为Deux在您声明map<>时是未知的。

你需要map<Deux, long>之前声明Deux,因为map<Deux, long>需要其参数的完整定义。

缺少比较器。

`error: no match for 'operator<' in '__x < __y'` 

那是因为你还没有为Deux定义operator<

如果你可以定义一个逻辑operator<,即一个不是出于排序目的而任意选择的逻辑,你可以这样做:

// must be in same namespace as Deux
bool operator< (Deux const &lhs, Deux const &rhs) {
    return lhs.foo < rhs.foo;
}

如果它需要访问非公共成员,您可以将其设置为成员函数:

bool operator< (Deux const &rhs) {
    return this->foo < rhs.foo;
}

如果这种比较是任意的,那就按照君士坦丁尼的建议去做。


下次

您可以通过发布您的实际代码或最小的测试用例以及提及错误消息来节省我们的时间。

我的猜测是您的结构缺少一个compare函数,可以将Deux对象作为键进行内部排序。在地图中,必须对它们进行排序。

这是std::map的定义

template < class Key, class T, class Compare = less<Key>,
           class Allocator = allocator<pair<const Key,T> > > class map;

因此,如果您定义这样的函数:

bool compare_deux(Deux& a, Deux& b) {
    return a.big < b.big;
}

并将其作为模板参数传递:

map <Deux, long, compare_deux> lengths;

你应该没事的。

使用 make_pair。

lengths.insert(make_pair<Deux,long>(d,one));

只是为了添加另一个回复,这是我如何实现严格排序Deux。我们只使用词典排序:

struct Deux
{
  long big, small;
  inline bool operator<(const Deux & o) const
  {
    return big < o.big || (!(o.big < big) && small < o.small);
  }
};
std::map<Deux, T> m; // works now!

或者,我们可以免除自己的痛苦,并说:

typedef std::pair<long, long> Deux;
std::map<Deux, T> m; // always works, lexicographic compare is provided by default

总是最好不要重新发明轮子!

如果您还希望使用 hash_combine 进行配对哈希以使用无序容器,请发表评论。

您需要

在创建地图时声明<运算符或传递比较函数。>

struct Deux     
{
  long big; 
  long small
  bool operator < (const Deux &n) const
  {         
    if(big != n.big)
       return big < n.big;
    else
       return small < n.small;
   }
};