我有一个类来存储如下所示的数据:
class DataLine
{
public:
std::string name;
boost::posix_time::time_duration time;
double x, y, z;
DataLine(std::string _name, boost::posix_time::time_duration _time, double _x,
double _y, double _z); //assign all these, not going to do it here
bool operator < (DataLine* dataLine) { return time < dataLine->time; }
}
然后我读了一堆数据并将它插入到std ::对象集中:
std::set<DataLine*> data;
data.insert( new DataLine(newname, newtime, newx, newy, newz) );
//...insert all data - IS OUT OF ORDER HERE
然后我运行我的数据并用它做任务,同时将新元素添加到集合中。
boost::posix_time::time_duration machineTime(0,0,0);
for(std::set<DataLine*>::reverse_iterator it = data.rbegin(); it != data.rend(); ++it)
{
if(machineTime < (*it)->time)
{
machineTime = (*it)->time;
}
machineTime += processDataLine(*it); //do stuff with data, might add to append list below
for(std::vector<AppendList*>::iterator iter = appendList.begin(); iter != appendList.end(); ++iter)
{
data.insert( new DataLine( (*iter)->name, machineTime,
(*iter)->x, (*iter)->y, (*iter)->z); );
}
}
当我尝试在插入元素之前和之后循环遍历数据集时,我的所有数据都不正常!使用
循环时会输出一些时间for(std::set<DataLine*>::iterator it = data.begin(); it != data.end(); ++it)
{
std::cout << std::endl << (*it)->time;
}
14:39:55.003001
14:39:55.003002
14:39:55.001000
14:39:59.122000
14:39:58.697000
14:39:57.576000
14:39:56.980000
为什么这些时间不按顺序排序?
答案 0 :(得分:4)
已排序。它根据您存储在集合中的数据类型进行排序,该数据类型是{em>指针到DataLine
。换句话说,它将根据对象的内存中的位置进行排序,这可能是可能创建顺序(但可能不是,取决于内存分配函数在您的实现中的工作方式)。
如果要根据DataLine
类型本身进行排序,请不要使用指针。存储对象本身。
您可以从以下代码中看到类似的效果,该代码会创建两个集合。第一个是一组整数指针,第二个是一组实际整数:
#include <iostream>
#include <iomanip>
#include <set>
using namespace std;
int main (void) {
set<int*> ipset;
set<int> iset;
cout << "inserting: ";
for (int i = 0; i < 10; i++) {
int val = (i * 7) % 13;
cout << ' ' << setw(2) << val;
ipset.insert (new int (val));
iset.insert (val);
}
cout << '\n';
cout << "integer pointer set:";
for (set<int*>::iterator it = ipset.begin(); it != ipset.end(); ++it)
cout << ' ' << setw(2) << **it;
cout << '\n';
cout << "integer set: ";
for (set<int>::iterator it = iset.begin(); it != iset.end(); ++it)
cout << ' ' << setw(2) << *it;
cout << '\n';
cout << "integer pointer set pointers:\n";
for (set<int*>::iterator it = ipset.begin(); it != ipset.end(); ++it)
cout << " " << *it << '\n';
cout << '\n';
return 0;
}
运行该代码时,您会看到以下内容:
inserting: 0 7 1 8 2 9 3 10 4 11
integer pointer set: 0 7 1 8 2 9 3 10 4 11
integer set: 0 1 2 3 4 7 8 9 10 11
integer pointer set pointers:
0x907c020
0x907c060
0x907c0a0
0x907c0e0
0x907c120
0x907c160
0x907c1a0
0x907c1e0
0x907c220
0x907c260
您可以看到将值添加到两个集合(第一行)的无序方式以及此情况下指针设置的方式与输入顺序(第二行)匹配。那是因为地址是用于排序的地方,因为你可以看到最后一节显示了有序地址。
虽然如上所述,它可能必然匹配输入顺序,因为内存竞技场可能有点碎片(作为一个例子)。
包含实际整数的集合(与整数指针相对)显然按整数值本身排序(第三行)。
答案 1 :(得分:2)
您需要像下面一样定义成员operator <
,并将对象保存在std::set
而不是原始指针中。因为对于原始指针,默认的比较标准基于指针值本身。
bool operator < (const DataLine &dataLine) const
{
return time < dataLine.time;
}
...
std::set<DataLine> data;