请注意,这里的问题已解决,与插入无关,而是未初始化的struct成员变量!希望这个问题及其答案可以帮助另一个新秀避免这种错误。
我想将文件名的std :: vector插入到std :: set中,该std :: set具有用于按日期而非按字母顺序排序文件的客户排序器结构。
使用默认的字母顺序,我可以使用以下命令简单地将向量插入我的集合中:
std::set<std::string> mySet;
std::vector<std::string> myVector;
myVector.push_back("Banana.txt");
myVector.push_back("Apple.txt");
myVector.push_back("Cat.txt");
mySet.insert(myVector.begin(), myVector.end());
这将给我确切的期望:一个std :: set文件名,按字母顺序排序。
现在,如果我有一个按日期而不是文件名排序的自定义排序器,就像这样:
struct DateOrderSorter
{
bool operator()(const std::string& file1, const std::string& file2)
{
struct stat buf_stat1;
struct stat buf_stat2;
std::string fullpath1 = path + file1;
std::string fullpath2 = path + file2;
stat(&fullpath1[0], &buf_stat1);
stat(&fullpath2[0], &buf_stat2);
return buf_stat1.st_ctime < buf_stat2.st_ctime;
}
std::string path;
};
我声明我的集合为:
std::set<std::string, DateOrderSorter>
,然后声明DateOrderSorter的实例:
DateOrderSorter dateOrderSorter;
dateOrderSorter.path = "C:/random_path_that_has_been_verified_to_work"
当我执行相同的插入操作时:
mySet.insert(myVector.begin(), myVector.end());
它仅返回按日期排序的第一个和最后一个文件。所以就是myVector.begin()和myVector.end()。
我尝试过
std::vector<std::string>::iterator vector_it = myVector.begin();
std::vector<std::string>::iterator vector_end = myVector.end();
for (; vector_it!= vector_end; ++vector_it) {
mySet.insert(*vector_it);
}
但是,这并没有完全复制向量,而且顺序很奇怪。它没有遵循名称或日期顺序。
答案 0 :(得分:2)
比较函数的path
成员默认初始化为“”,因此出现stat
错误(由于未在代码中检查返回值,因此错误未引起注意)和{{1 }}正在比较未初始化的内存。
这意味着比较函数可以对buf_stat1.st_ctime < buf_stat2.st_ctime
和a < b
都返回true:这违反了strict weak ordering的规则,因此您观察到这种奇怪的行为。
要解决此问题,您可以将a > b
设为静态成员,并确认path
不会出错,就像这样:
stat
并像这样初始化它:
struct DateOrderSorter
{
bool operator()(const std::string& file1, const std::string& file2)
{
struct stat buf_stat1;
struct stat buf_stat2;
std::string fullpath1 = path + file1;
std::string fullpath2 = path + file2;
int r = stat(&fullpath1[0], &buf_stat1);
assert(r==0);
r = stat(&fullpath2[0], &buf_stat2);
assert(r==0);
return buf_stat1.st_ctime < buf_stat2.st_ctime;
}
static std::string path;
};
答案 1 :(得分:0)
因为ctime
表明现在是Posix时间,即秒刻度。当然,两个不同的文件这次可能具有相同的值,这实际上意味着文件状态的最后一次更改。尝试使用std::mutiset
。