【发布时间】:2021-10-27 13:50:44
【问题描述】:
这一定是非常愚蠢的事情,但我无法从中获得正面或反面。 这是测试代码。
#include <iostream>
#include <vector>
#include <limits>
#include <random>
#include <map>
#include <set>
#include <stdlib.h>
class value_randomized
{
public:
double value;
long random;
value_randomized()
{
value=0;
random=0;
}
/*
bool operator<(const value_randomized& b) const
{
if (value<b.value) return true;
return (random<b.random);
}
*/
friend bool operator<(const value_randomized& a, const value_randomized& b);
};
inline bool operator<(const value_randomized& a, const value_randomized& b)
{
return (a.value<b.value)?true:(a.random<b.random);
}
int main(int argc, char *argv[])
{
std::map<value_randomized,size_t> results;
for (size_t i=0; i<1000; ++i)
{
value_randomized r;
r.value=rand();
r.value/=RAND_MAX;
r.random=rand();
results.insert(std::make_pair(r, i));
}
std::multiset<value_randomized> s;
for (size_t i=0; i<1000; ++i)
{
value_randomized r;
r.value=rand();
r.value/=RAND_MAX;
r.random=rand();
s.insert(r);
}
return 0;
}
我已经尝试在类内和类外重载 operator
即使直接打印 multiset 的值也会给出一些明显无序的结果。这是第一个结果
(0.0515083,114723506)
(0.0995593,822262754)
(0.0491625,964445884)
(0.410788,11614769)
(0.107848,1389867269)
(0.15123,155789224)
(0.293678,246247255)
(0.331386,195740084)
(0.138238,774044599)
(0.178208,476667372)
(0.162757,588219756)
(0.244327,700108581)
(0.329642,407487131)
(0.363598,619054081)
(0.111276,776532036)
(0.180421,1469262009)
(0.121143,1472713773)
(0.188201,937370163)
(0.210883,1017679567)
(0.301763,1411154259)
(0.394327,1414829150)
(0.383832,1662739668)
(0.260497,1884167637)
显然我遗漏了什么,但是什么?
【问题讨论】:
-
您的比较器错误(损坏的weak ordering)。请改用
return std::tie(a.value, a.random) < std::tie(b.value, b.random);。 -
@Jarod42 它有效。谢谢。但是为什么逐个字段比较它不起作用呢?编辑:哦,我看到了链接。我要读它。再次感谢。
-
...这是错误的,因为它会将
(0.6, 1)之类的东西视为小于(0.5, 2)。这不是字典顺序的实现方式。 -
(a.value<b.value)?true:(a.random<b.random);等价于a.value < b.value || a.random < b.random。这意味着{0,1}和{1,0}都排在另一个之前,这是不可能的。 -
现在我看到了问题所在。再次感谢,伙计们!
标签: c++ operator-overloading stdmap stdset