【问题标题】:How to instantiate an comparison function (functor) when defining a map/set?定义映射/集合时如何实例化比较函数(函子)?
【发布时间】:2013-10-13 15:42:21
【问题描述】:

我正在使用一个函数对象来为 map/set 指定一个比较函数:

struct CompareObject {
    bool operator()(Node* const n1, Node* const n2) const;
}; 

据我了解,定义这样的集合不会创建任何 CompareObject 实例,并且会假装它是静态的:

std::multiset<Node*, CompareObject> set;

但在我的问题中,我需要将 Tree 的实例传递给它,因为我在实际的比较函数中使用它:

bool
CompareObject::operator()(Node* const n1, Node* const n2) const {
  if (tree->getNoOfGood(n1) > tree->getNoOfGood(n2)) return false;
  if (tree->getNoOfGood(n2) > tree->getNoOfGood(n1)) return true;
  return false;
}

所以,我在 CompareObject 定义中添加了一些字段:

struct CompareObject {

  Tree& tree;              // added
  CompareObject(Tree& t);  // added

  bool operator()(Node* const n1, Node* const n2) const;
}; 

我遇到的问题是我不知道如何用集合的定义来实例化这个对象。

我首先想到的是:

std::multiset<Node*, CompareObjects(*this)> shapesMap; // not valid code

但不出所料,它给了我一个错误:‘this’不能出现在常量表达式中

你有什么想法可以解决这个问题吗?

【问题讨论】:

  • 注意Node*const nNode const *nconst Node* n 之间的区别。第一种情况const适用于指针,所以我们不能让n指向另一个对象,但是可以改变这个指针下的数据:n-&gt;x=22是可能的。第二和第三符号不允许更改指针下的对象。 您可能想要使用第二个或第三个变体。

标签: c++ std functor multiset


【解决方案1】:

您可以将仿函数的实例作为参数传递给集合构造函数。所以像multiset&lt;Node*, CompareObject&gt; shapesSet(CompareObject(myTree));

【讨论】:

  • @msgmaxim 我认为编译器可能会将初始化解析为函数声明。尝试在 CompareObject 周围添加一组额外的括号:multiset&lt;Node*, CompareObject&gt; shapesSet((CompareObject(myTree)));。如果你使用的是 C++11,也可以使用统一初始化:shapesSet{CompareObject{myTree}};
  • 额外的括号没有帮助,但统一初始化似乎解决了这个问题。顺便说一句,初始化列表也可以正常工作!
猜你喜欢
  • 1970-01-01
  • 2023-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2019-02-22
相关资源
最近更新 更多