C++ 集合的结构之间的比较

C++ 集合的结构之间的比较,c++,set,c++14,smart-pointers,C++,Set,C++14,Smart Pointers,这段代码可以工作,但在加权指针之外有一个名为ptrcomp的结构(对我来说)似乎是不同的东西。我尝试了一些不同的方法,甚至在谷歌上搜索过,但我还没有找到任何像这样有效的方法 struct node{ unsigned int oper; void * a; void * b; }; struct weighted_pointer{ mutable int weight; unique_ptr<node> pointer; }; struct

这段代码可以工作,但在
加权指针
之外有一个名为
ptrcomp
的结构(对我来说)似乎是不同的东西。我尝试了一些不同的方法,甚至在谷歌上搜索过,但我还没有找到任何像这样有效的方法

struct node{
    unsigned int oper;
    void * a;
    void * b;
};

struct weighted_pointer{
    mutable int weight;
    unique_ptr<node> pointer;
};

struct ptrcomp{
    bool operator()(const weighted_pointer & lhs, const weighted_pointer & rhs) {
        return tie(lhs.pointer->oper, lhs.pointer->a, lhs.pointer->b) < tie(rhs.pointer->oper, rhs.pointer->a, rhs.pointer->b);
    }
};

set<weighted_pointer,ptrcomp> gate;
struct节点{
无符号整数运算;
无效*a;
无效*b;
};
结构加权指针{
可变整数权重;
唯一的ptr指针;
};
结构ptrcomp{
布尔运算符(){
返回tie(左指针->操作,左指针->a,左指针->b)操作,右指针->a,右指针->b);
}
};
设置闸门;
我的目标是使
std::set
工作。并可能像
set
那样编写它

在加权_指针之外有一个名为ptrcomp的结构(对我来说)似乎是不同的东西

事情就是这样
weighted_pointer
是数据,而
ptrcomp
是比较数据的一种方法。所以,这两个是不同的东西,你的代码没有什么问题

如果您有一种比较数据的标准方法,请将其设置为
操作符oper,lhs.pointer->a,lhs.pointer->b)oper,rhs.pointer->a,rhs.pointer->b);
}

std::set
将乐于使用它,如果您将其用作
std::set
(事实上,
std::set
的第二个模板参数默认为
std::less
,这是一个比较器类,如果您将代码更改为

struct weighted_pointer {
    mutable int weight;
    unique_ptr<node> pointer;

    bool operator < (const weighted_pointer & rhs) const;
};

bool weighted_pointer::operator < (const weighted_pointer & rhs) const {
    return tie(pointer->oper, pointer->a, pointer->b) < tie(rhs.pointer->oper, rhs.pointer->a, rhs.pointer->b);
}
struct加权\u指针{
可变整数权重;
唯一的ptr指针;
布尔运算符<(常数加权指针和rhs)常数;
};
布尔加权指针::运算符<(常数加权指针和rhs)常数{
返回tie(指针->操作,指针->a,指针->b)操作,右指针->a,右指针->b);
}
然后它就可以工作了,您不需要为
集合
使用比较器
ptrcomp
,并且可以根据需要使用类型
集合
。(如果您愿意,也可以将定义移动到结构中。)

结构加权指针{
// ...
结构比较{
// ...
};
};
设置闸门;
//更好
使用加权指针集=集;
加权指针设置门;
这就是我通常看到的情况


拥有
std::set
意味着set使用
std::less
来比较元素。这反过来调用
operator您看到了什么错误?您希望
set
如何对这些对象进行排序?@sfjac此代码中没有错误。而且它的排序方式正确。但我不想使用
ptrcomp
结构。我想知道是否有可能用另一种方法来避免创建另一个结构。我应该在哪里添加此代码?在我的版本中,
weighted_指针
struct?@UmurilLyerood内,它只是一个免费函数-放在任何你想要的地方(如果您将实现放在某个标题中,请不要忘记
inline
关键字)。不同的是,您可以将其作为一种
加权_指针的方法,如@R2 Dequeue answer所示。谢谢,这正是我想要的。(将定义放入结构中)。通过这种方式,可以清楚地知道它使用的是什么运算符。我写了几次,但都不起作用,现在我发现我在参数后缺少了常量。你能解释一下它的用途吗?
const
,方法声明告诉编译器你不会修改该类/结构实例的任何成员数据。如果do或您调用的某个操作,这是一个错误并停止编译。当您知道您只想使用而不想更改数据时,这有助于防止意外修改数据。很有用!但我怎么知道(如本例所示)当std需要它时?有没有写过任何引用?好吧,对于像这样带有比较运算符的情况,我从来没有真正想到过它;它现在对我来说是如此自动(添加
const
,这是一个很好的实践,如果你后来意识到你真的想用一个操作修改对象,那么很容易更改)。也就是说,删除
const
(在结构内定义和外部声明中)并不能阻止它在VS2015中为我编译。如果你真的插入数据,它会失败吗?它是单独编译的。但是当我使用它时:
gate.insert(move(加权指针{1,使指针唯一(*move指针));
。它给了我一个错误。
struct weighted_pointer {
    mutable int weight;
    unique_ptr<node> pointer;

    bool operator < (const weighted_pointer & rhs) const;
};

bool weighted_pointer::operator < (const weighted_pointer & rhs) const {
    return tie(pointer->oper, pointer->a, pointer->b) < tie(rhs.pointer->oper, rhs.pointer->a, rhs.pointer->b);
}
struct weighted_pointer {
 // ...
 struct compare {
  // ...
  };
};


set<weighted_pointer,weighted_pointer::compare> gate;

// better

using weighted_pointer_set = set<weighted_pointer,weighted_pointer::compare>;
weighted_pointer_set gate;