包含一组自带的自定义比较器的类 - 循环引用

时间:2016-11-22 20:02:58

标签: c++ templates set

这是目标(当然是简化代码):

#include <set>

struct Node
{
   int Value;
   std::set<Node*, CompareNodes> Children;
};

struct CompareNodes
{
   bool operator()(const Node* l, const Node* r)
   {
      return l->Value < r->Value;
   }
};

但这并没有编译;在CompareNodes内遇到Node类型时,它是未知的。我可以改变顺序,但后来我遇到了相反的问题 - NodeCompareNodes内遇到时会不知道。在任何一种情况下,前向声明都没有帮助,因为每种类型都以需要完全定义的方式使用另一种类型。一个丑陋的解决方法是:

#include <set>

template<typename T>
struct CompareNodes
{
   bool operator()(const T* l, const T* r)
   {
      return l->Value < r->Value;
   }
};

struct Node
{
   int Value;
   std::set<Node*, CompareNodes<Node>> Children;
};

有更好的方法吗?如果答案在Node是内部类别时仍然有效,则奖励积分。

3 个答案:

答案 0 :(得分:3)

您可以使用嵌套类作为比较器:

#include <set>

struct Node
{
   struct CompareNodes
   {
      bool operator()(const Node& l, const Node& r)
      {
         return l.Value < r.Value;
      }
   };

   int Value;
   std::set<Node, CompareNodes> Children;
};

答案 1 :(得分:2)

  

前提声明在任何一种情况下都没有帮助

不完全正确。前瞻声明将正常运作:

#include <set>

struct Node;

struct CompareNodes
{
    bool operator()(const Node& l, const Node& r);
};

struct Node
{
   int Value;
   std::set<Node, CompareNodes> Children;
};

bool CompareNodes::operator()(const Node& l, const Node& r)
{
    return l.Value < r.Value;
}

如果需要在头文件中声明operator()成员函数,则需要将inline关键字粘贴到其中。

答案 2 :(得分:1)

也许您可以使用模板来延迟完整性检查直到使用?

#include <set>

struct CompareNodes;

template <class Cmp = CompareNodes>
struct Node
{
   int Value;
   std::set<Node*, Cmp> Children;
};

struct CompareNodes
{
   bool operator()(const Node<>* l, const Node<>* r)
   {
      return l->Value < r->Value;
   }
};

int main() {
    Node<> n;
}